diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2015-01-11 22:33:32 -0500 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2015-01-12 04:26:07 -0500 |
commit | d7f72f61955ded6ae5f0381dcde1fcadce8833bb (patch) | |
tree | 4e42133ca1be9c6f7a45badd7448d6d28a841565 /net/bluetooth/hci_sock.c | |
parent | 2b531294b02454b6aa189f99ea8982bdd0d7b3bb (diff) |
Bluetooth: Create generic queue_monitor_skb helper function
The hci_send_to_monitor function contains generic code for queueing the
packet into the receive queue of every monitor client. To avoid code
duplication, create a generic queue_monitor_skb function to interate
over all monitor sockets.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth/hci_sock.c')
-rw-r--r-- | net/bluetooth/hci_sock.c | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 026e84a80659..1987ea178b7d 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -216,10 +216,37 @@ void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk) | |||
216 | read_unlock(&hci_sk_list.lock); | 216 | read_unlock(&hci_sk_list.lock); |
217 | } | 217 | } |
218 | 218 | ||
219 | static void queue_monitor_skb(struct sk_buff *skb) | ||
220 | { | ||
221 | struct sock *sk; | ||
222 | |||
223 | BT_DBG("len %d", skb->len); | ||
224 | |||
225 | read_lock(&hci_sk_list.lock); | ||
226 | |||
227 | sk_for_each(sk, &hci_sk_list.head) { | ||
228 | struct sk_buff *nskb; | ||
229 | |||
230 | if (sk->sk_state != BT_BOUND) | ||
231 | continue; | ||
232 | |||
233 | if (hci_pi(sk)->channel != HCI_CHANNEL_MONITOR) | ||
234 | continue; | ||
235 | |||
236 | nskb = skb_clone(skb, GFP_ATOMIC); | ||
237 | if (!nskb) | ||
238 | continue; | ||
239 | |||
240 | if (sock_queue_rcv_skb(sk, nskb)) | ||
241 | kfree_skb(nskb); | ||
242 | } | ||
243 | |||
244 | read_unlock(&hci_sk_list.lock); | ||
245 | } | ||
246 | |||
219 | /* Send frame to monitor socket */ | 247 | /* Send frame to monitor socket */ |
220 | void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) | 248 | void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) |
221 | { | 249 | { |
222 | struct sock *sk; | ||
223 | struct sk_buff *skb_copy = NULL; | 250 | struct sk_buff *skb_copy = NULL; |
224 | struct hci_mon_hdr *hdr; | 251 | struct hci_mon_hdr *hdr; |
225 | __le16 opcode; | 252 | __le16 opcode; |
@@ -263,27 +290,7 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) | |||
263 | hdr->index = cpu_to_le16(hdev->id); | 290 | hdr->index = cpu_to_le16(hdev->id); |
264 | hdr->len = cpu_to_le16(skb->len); | 291 | hdr->len = cpu_to_le16(skb->len); |
265 | 292 | ||
266 | read_lock(&hci_sk_list.lock); | 293 | queue_monitor_skb(skb_copy); |
267 | |||
268 | sk_for_each(sk, &hci_sk_list.head) { | ||
269 | struct sk_buff *nskb; | ||
270 | |||
271 | if (sk->sk_state != BT_BOUND) | ||
272 | continue; | ||
273 | |||
274 | if (hci_pi(sk)->channel != HCI_CHANNEL_MONITOR) | ||
275 | continue; | ||
276 | |||
277 | nskb = skb_clone(skb_copy, GFP_ATOMIC); | ||
278 | if (!nskb) | ||
279 | continue; | ||
280 | |||
281 | if (sock_queue_rcv_skb(sk, nskb)) | ||
282 | kfree_skb(nskb); | ||
283 | } | ||
284 | |||
285 | read_unlock(&hci_sk_list.lock); | ||
286 | |||
287 | kfree_skb(skb_copy); | 294 | kfree_skb(skb_copy); |
288 | } | 295 | } |
289 | 296 | ||