diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2015-03-14 22:27:59 -0400 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2015-03-15 03:56:41 -0400 |
commit | c08b1a1dba524c1cdef331c1f169db3a1b37bb4c (patch) | |
tree | e4b2abbdb127002e22ae36b1c1a124cfaae7bf5f /net | |
parent | 50ebc055fa758c731e6e1ce174608327aab07aec (diff) |
Bluetooth: Consolidate socket channel sending function back into one
With the introduction of trusted socket flag for control and monitor
channels, it is now possible to use a single function for sending
packets to these sockets. And with that consolidate the handling.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_sock.c | 45 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 34 |
2 files changed, 16 insertions, 63 deletions
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 54118868b3f6..e7f463f6fd69 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -199,7 +199,7 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) | |||
199 | 199 | ||
200 | /* Send frame to sockets with specific channel */ | 200 | /* Send frame to sockets with specific channel */ |
201 | void hci_send_to_channel(unsigned short channel, struct sk_buff *skb, | 201 | void hci_send_to_channel(unsigned short channel, struct sk_buff *skb, |
202 | struct sock *skip_sk) | 202 | int flag, struct sock *skip_sk) |
203 | { | 203 | { |
204 | struct sock *sk; | 204 | struct sock *sk; |
205 | 205 | ||
@@ -210,41 +210,12 @@ void hci_send_to_channel(unsigned short channel, struct sk_buff *skb, | |||
210 | sk_for_each(sk, &hci_sk_list.head) { | 210 | sk_for_each(sk, &hci_sk_list.head) { |
211 | struct sk_buff *nskb; | 211 | struct sk_buff *nskb; |
212 | 212 | ||
213 | /* Skip the original socket */ | 213 | /* Ignore socket without the flag set */ |
214 | if (sk == skip_sk) | 214 | if (!test_bit(flag, &hci_pi(sk)->flags)) |
215 | continue; | ||
216 | |||
217 | if (sk->sk_state != BT_BOUND) | ||
218 | continue; | ||
219 | |||
220 | if (hci_pi(sk)->channel != channel) | ||
221 | continue; | ||
222 | |||
223 | nskb = skb_clone(skb, GFP_ATOMIC); | ||
224 | if (!nskb) | ||
225 | continue; | 215 | continue; |
226 | 216 | ||
227 | if (sock_queue_rcv_skb(sk, nskb)) | 217 | /* Skip the original socket */ |
228 | kfree_skb(nskb); | 218 | if (sk == skip_sk) |
229 | } | ||
230 | |||
231 | read_unlock(&hci_sk_list.lock); | ||
232 | } | ||
233 | |||
234 | /* Send frame to sockets with specific channel flag set */ | ||
235 | void hci_send_to_flagged_channel(unsigned short channel, struct sk_buff *skb, | ||
236 | int flag) | ||
237 | { | ||
238 | struct sock *sk; | ||
239 | |||
240 | BT_DBG("channel %u len %d", channel, skb->len); | ||
241 | |||
242 | read_lock(&hci_sk_list.lock); | ||
243 | |||
244 | sk_for_each(sk, &hci_sk_list.head) { | ||
245 | struct sk_buff *nskb; | ||
246 | |||
247 | if (!test_bit(flag, &hci_pi(sk)->flags)) | ||
248 | continue; | 219 | continue; |
249 | 220 | ||
250 | if (sk->sk_state != BT_BOUND) | 221 | if (sk->sk_state != BT_BOUND) |
@@ -310,7 +281,8 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) | |||
310 | hdr->index = cpu_to_le16(hdev->id); | 281 | hdr->index = cpu_to_le16(hdev->id); |
311 | hdr->len = cpu_to_le16(skb->len); | 282 | hdr->len = cpu_to_le16(skb->len); |
312 | 283 | ||
313 | hci_send_to_channel(HCI_CHANNEL_MONITOR, skb_copy, NULL); | 284 | hci_send_to_channel(HCI_CHANNEL_MONITOR, skb_copy, |
285 | HCI_SOCK_TRUSTED, NULL); | ||
314 | kfree_skb(skb_copy); | 286 | kfree_skb(skb_copy); |
315 | } | 287 | } |
316 | 288 | ||
@@ -417,7 +389,8 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) | |||
417 | 389 | ||
418 | skb = create_monitor_event(hdev, event); | 390 | skb = create_monitor_event(hdev, event); |
419 | if (skb) { | 391 | if (skb) { |
420 | hci_send_to_channel(HCI_CHANNEL_MONITOR, skb, NULL); | 392 | hci_send_to_channel(HCI_CHANNEL_MONITOR, skb, |
393 | HCI_SOCK_TRUSTED, NULL); | ||
421 | kfree_skb(skb); | 394 | kfree_skb(skb); |
422 | } | 395 | } |
423 | } | 396 | } |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index ff636bd9523b..1e5afa76e371 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -224,7 +224,7 @@ static u8 mgmt_status(u8 hci_status) | |||
224 | 224 | ||
225 | static int mgmt_send_event(u16 event, struct hci_dev *hdev, | 225 | static int mgmt_send_event(u16 event, struct hci_dev *hdev, |
226 | unsigned short channel, void *data, u16 data_len, | 226 | unsigned short channel, void *data, u16 data_len, |
227 | struct sock *skip_sk) | 227 | int flag, struct sock *skip_sk) |
228 | { | 228 | { |
229 | struct sk_buff *skb; | 229 | struct sk_buff *skb; |
230 | struct mgmt_hdr *hdr; | 230 | struct mgmt_hdr *hdr; |
@@ -247,44 +247,24 @@ static int mgmt_send_event(u16 event, struct hci_dev *hdev, | |||
247 | /* Time stamp */ | 247 | /* Time stamp */ |
248 | __net_timestamp(skb); | 248 | __net_timestamp(skb); |
249 | 249 | ||
250 | hci_send_to_channel(channel, skb, skip_sk); | 250 | hci_send_to_channel(channel, skb, flag, skip_sk); |
251 | kfree_skb(skb); | 251 | kfree_skb(skb); |
252 | 252 | ||
253 | return 0; | 253 | return 0; |
254 | } | 254 | } |
255 | 255 | ||
256 | static int mgmt_index_event(u16 event, struct hci_dev *hdev, | 256 | static int mgmt_index_event(u16 event, struct hci_dev *hdev, void *data, |
257 | void *data, u16 data_len, int flag) | 257 | u16 len, int flag) |
258 | { | 258 | { |
259 | struct sk_buff *skb; | 259 | return mgmt_send_event(event, hdev, HCI_CHANNEL_CONTROL, data, len, |
260 | struct mgmt_hdr *hdr; | 260 | flag, NULL); |
261 | |||
262 | skb = alloc_skb(sizeof(*hdr) + data_len, GFP_KERNEL); | ||
263 | if (!skb) | ||
264 | return -ENOMEM; | ||
265 | |||
266 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | ||
267 | hdr->opcode = cpu_to_le16(event); | ||
268 | hdr->index = cpu_to_le16(hdev->id); | ||
269 | hdr->len = cpu_to_le16(data_len); | ||
270 | |||
271 | if (data) | ||
272 | memcpy(skb_put(skb, data_len), data, data_len); | ||
273 | |||
274 | /* Time stamp */ | ||
275 | __net_timestamp(skb); | ||
276 | |||
277 | hci_send_to_flagged_channel(HCI_CHANNEL_CONTROL, skb, flag); | ||
278 | kfree_skb(skb); | ||
279 | |||
280 | return 0; | ||
281 | } | 261 | } |
282 | 262 | ||
283 | static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 len, | 263 | static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 len, |
284 | struct sock *skip_sk) | 264 | struct sock *skip_sk) |
285 | { | 265 | { |
286 | return mgmt_send_event(event, hdev, HCI_CHANNEL_CONTROL, data, len, | 266 | return mgmt_send_event(event, hdev, HCI_CHANNEL_CONTROL, data, len, |
287 | skip_sk); | 267 | HCI_SOCK_TRUSTED, skip_sk); |
288 | } | 268 | } |
289 | 269 | ||
290 | static int mgmt_cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) | 270 | static int mgmt_cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) |