blob: 9c6d9bc1d8afeff0736ffe0551165b2e2c742d3b [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
38#include <linux/notifier.h>
39#include <net/sock.h>
40
41#include <asm/system.h>
42#include <asm/uaccess.h>
43#include <asm/unaligned.h>
44
45#include <net/bluetooth/bluetooth.h>
46#include <net/bluetooth/hci_core.h>
47
Linus Torvalds1da177e2005-04-16 15:20:36 -070048/* Handle HCI Event packets */
49
Marcel Holtmanna9de9242007-10-20 13:33:56 +020050static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070051{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
Marcel Holtmanna9de9242007-10-20 13:33:56 +020054 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Marcel Holtmanna9de9242007-10-20 13:33:56 +020056 if (status)
57 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Marcel Holtmanna9de9242007-10-20 13:33:56 +020059 clear_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010060
Marcel Holtmanna9de9242007-10-20 13:33:56 +020061 hci_req_complete(hdev, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010062
Marcel Holtmanna9de9242007-10-20 13:33:56 +020063 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070064}
65
Marcel Holtmanna9de9242007-10-20 13:33:56 +020066static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020068 __u8 status = *((__u8 *) skb->data);
69
70 BT_DBG("%s status 0x%x", hdev->name, status);
71
72 if (status)
73 return;
74
75 clear_bit(HCI_INQUIRY, &hdev->flags);
76
77 hci_conn_check_pending(hdev);
78}
79
80static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
81{
82 BT_DBG("%s", hdev->name);
83}
84
85static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
86{
87 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
Marcel Holtmanna9de9242007-10-20 13:33:56 +020090 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
Marcel Holtmanna9de9242007-10-20 13:33:56 +020092 if (rp->status)
93 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
98 if (conn) {
99 if (rp->role)
100 conn->link_mode &= ~HCI_LM_MASTER;
101 else
102 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200104
105 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106}
107
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200108static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
109{
110 struct hci_rp_read_link_policy *rp = (void *) skb->data;
111 struct hci_conn *conn;
112
113 BT_DBG("%s status 0x%x", hdev->name, rp->status);
114
115 if (rp->status)
116 return;
117
118 hci_dev_lock(hdev);
119
120 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
121 if (conn)
122 conn->link_policy = __le16_to_cpu(rp->policy);
123
124 hci_dev_unlock(hdev);
125}
126
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200127static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200129 struct hci_rp_write_link_policy *rp = (void *) skb->data;
130 struct hci_conn *conn;
131 void *sent;
132
133 BT_DBG("%s status 0x%x", hdev->name, rp->status);
134
135 if (rp->status)
136 return;
137
138 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
139 if (!sent)
140 return;
141
142 hci_dev_lock(hdev);
143
144 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200145 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700146 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200147
148 hci_dev_unlock(hdev);
149}
150
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200151static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
152{
153 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
154
155 BT_DBG("%s status 0x%x", hdev->name, rp->status);
156
157 if (rp->status)
158 return;
159
160 hdev->link_policy = __le16_to_cpu(rp->policy);
161}
162
163static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
164{
165 __u8 status = *((__u8 *) skb->data);
166 void *sent;
167
168 BT_DBG("%s status 0x%x", hdev->name, status);
169
170 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
171 if (!sent)
172 return;
173
174 if (!status)
175 hdev->link_policy = get_unaligned_le16(sent);
176
177 hci_req_complete(hdev, status);
178}
179
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200180static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
181{
182 __u8 status = *((__u8 *) skb->data);
183
184 BT_DBG("%s status 0x%x", hdev->name, status);
185
186 hci_req_complete(hdev, status);
187}
188
189static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
190{
191 __u8 status = *((__u8 *) skb->data);
192 void *sent;
193
194 BT_DBG("%s status 0x%x", hdev->name, status);
195
Marcel Holtmannf383f272008-07-14 20:13:47 +0200196 if (status)
197 return;
198
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200199 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
200 if (!sent)
201 return;
202
Marcel Holtmannf383f272008-07-14 20:13:47 +0200203 memcpy(hdev->dev_name, sent, 248);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200204}
205
206static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
207{
208 struct hci_rp_read_local_name *rp = (void *) skb->data;
209
210 BT_DBG("%s status 0x%x", hdev->name, rp->status);
211
212 if (rp->status)
213 return;
214
215 memcpy(hdev->dev_name, rp->name, 248);
216}
217
218static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
219{
220 __u8 status = *((__u8 *) skb->data);
221 void *sent;
222
223 BT_DBG("%s status 0x%x", hdev->name, status);
224
225 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
226 if (!sent)
227 return;
228
229 if (!status) {
230 __u8 param = *((__u8 *) sent);
231
232 if (param == AUTH_ENABLED)
233 set_bit(HCI_AUTH, &hdev->flags);
234 else
235 clear_bit(HCI_AUTH, &hdev->flags);
236 }
237
238 hci_req_complete(hdev, status);
239}
240
241static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
242{
243 __u8 status = *((__u8 *) skb->data);
244 void *sent;
245
246 BT_DBG("%s status 0x%x", hdev->name, status);
247
248 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
249 if (!sent)
250 return;
251
252 if (!status) {
253 __u8 param = *((__u8 *) sent);
254
255 if (param)
256 set_bit(HCI_ENCRYPT, &hdev->flags);
257 else
258 clear_bit(HCI_ENCRYPT, &hdev->flags);
259 }
260
261 hci_req_complete(hdev, status);
262}
263
264static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
265{
266 __u8 status = *((__u8 *) skb->data);
267 void *sent;
268
269 BT_DBG("%s status 0x%x", hdev->name, status);
270
271 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
272 if (!sent)
273 return;
274
275 if (!status) {
276 __u8 param = *((__u8 *) sent);
277
278 clear_bit(HCI_PSCAN, &hdev->flags);
279 clear_bit(HCI_ISCAN, &hdev->flags);
280
281 if (param & SCAN_INQUIRY)
282 set_bit(HCI_ISCAN, &hdev->flags);
283
284 if (param & SCAN_PAGE)
285 set_bit(HCI_PSCAN, &hdev->flags);
286 }
287
288 hci_req_complete(hdev, status);
289}
290
291static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
292{
293 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
294
295 BT_DBG("%s status 0x%x", hdev->name, rp->status);
296
297 if (rp->status)
298 return;
299
300 memcpy(hdev->dev_class, rp->dev_class, 3);
301
302 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
303 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
304}
305
306static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
307{
308 __u8 status = *((__u8 *) skb->data);
309 void *sent;
310
311 BT_DBG("%s status 0x%x", hdev->name, status);
312
Marcel Holtmannf383f272008-07-14 20:13:47 +0200313 if (status)
314 return;
315
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200316 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
317 if (!sent)
318 return;
319
Marcel Holtmannf383f272008-07-14 20:13:47 +0200320 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200321}
322
323static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
324{
325 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200327
328 BT_DBG("%s status 0x%x", hdev->name, rp->status);
329
330 if (rp->status)
331 return;
332
333 setting = __le16_to_cpu(rp->voice_setting);
334
Marcel Holtmannf383f272008-07-14 20:13:47 +0200335 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200336 return;
337
338 hdev->voice_setting = setting;
339
340 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
341
342 if (hdev->notify) {
343 tasklet_disable(&hdev->tx_task);
344 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
345 tasklet_enable(&hdev->tx_task);
346 }
347}
348
349static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
350{
351 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200352 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 void *sent;
354
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200355 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356
Marcel Holtmannf383f272008-07-14 20:13:47 +0200357 if (status)
358 return;
359
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200360 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
361 if (!sent)
362 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363
Marcel Holtmannf383f272008-07-14 20:13:47 +0200364 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
Marcel Holtmannf383f272008-07-14 20:13:47 +0200366 if (hdev->voice_setting == setting)
367 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368
Marcel Holtmannf383f272008-07-14 20:13:47 +0200369 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370
Marcel Holtmannf383f272008-07-14 20:13:47 +0200371 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
372
373 if (hdev->notify) {
374 tasklet_disable(&hdev->tx_task);
375 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
376 tasklet_enable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 }
378}
379
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200380static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200382 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200386 hci_req_complete(hdev, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387}
388
Marcel Holtmann333140b2008-07-14 20:13:48 +0200389static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
390{
391 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
392
393 BT_DBG("%s status 0x%x", hdev->name, rp->status);
394
395 if (rp->status)
396 return;
397
398 hdev->ssp_mode = rp->mode;
399}
400
401static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
402{
403 __u8 status = *((__u8 *) skb->data);
404 void *sent;
405
406 BT_DBG("%s status 0x%x", hdev->name, status);
407
408 if (status)
409 return;
410
411 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
412 if (!sent)
413 return;
414
415 hdev->ssp_mode = *((__u8 *) sent);
416}
417
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200418static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
419{
420 struct hci_rp_read_local_version *rp = (void *) skb->data;
421
422 BT_DBG("%s status 0x%x", hdev->name, rp->status);
423
424 if (rp->status)
425 return;
426
427 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200428 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
429 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200430
431 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
432 hdev->manufacturer,
433 hdev->hci_ver, hdev->hci_rev);
434}
435
436static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
437{
438 struct hci_rp_read_local_commands *rp = (void *) skb->data;
439
440 BT_DBG("%s status 0x%x", hdev->name, rp->status);
441
442 if (rp->status)
443 return;
444
445 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
446}
447
448static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
449{
450 struct hci_rp_read_local_features *rp = (void *) skb->data;
451
452 BT_DBG("%s status 0x%x", hdev->name, rp->status);
453
454 if (rp->status)
455 return;
456
457 memcpy(hdev->features, rp->features, 8);
458
459 /* Adjust default settings according to features
460 * supported by device. */
461
462 if (hdev->features[0] & LMP_3SLOT)
463 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
464
465 if (hdev->features[0] & LMP_5SLOT)
466 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
467
468 if (hdev->features[1] & LMP_HV2) {
469 hdev->pkt_type |= (HCI_HV2);
470 hdev->esco_type |= (ESCO_HV2);
471 }
472
473 if (hdev->features[1] & LMP_HV3) {
474 hdev->pkt_type |= (HCI_HV3);
475 hdev->esco_type |= (ESCO_HV3);
476 }
477
478 if (hdev->features[3] & LMP_ESCO)
479 hdev->esco_type |= (ESCO_EV3);
480
481 if (hdev->features[4] & LMP_EV4)
482 hdev->esco_type |= (ESCO_EV4);
483
484 if (hdev->features[4] & LMP_EV5)
485 hdev->esco_type |= (ESCO_EV5);
486
Marcel Holtmannefc76882009-02-06 09:13:37 +0100487 if (hdev->features[5] & LMP_EDR_ESCO_2M)
488 hdev->esco_type |= (ESCO_2EV3);
489
490 if (hdev->features[5] & LMP_EDR_ESCO_3M)
491 hdev->esco_type |= (ESCO_3EV3);
492
493 if (hdev->features[5] & LMP_EDR_3S_ESCO)
494 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
495
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200496 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
497 hdev->features[0], hdev->features[1],
498 hdev->features[2], hdev->features[3],
499 hdev->features[4], hdev->features[5],
500 hdev->features[6], hdev->features[7]);
501}
502
503static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
504{
505 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
506
507 BT_DBG("%s status 0x%x", hdev->name, rp->status);
508
509 if (rp->status)
510 return;
511
512 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
513 hdev->sco_mtu = rp->sco_mtu;
514 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
515 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
516
517 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
518 hdev->sco_mtu = 64;
519 hdev->sco_pkts = 8;
520 }
521
522 hdev->acl_cnt = hdev->acl_pkts;
523 hdev->sco_cnt = hdev->sco_pkts;
524
525 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
526 hdev->acl_mtu, hdev->acl_pkts,
527 hdev->sco_mtu, hdev->sco_pkts);
528}
529
530static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
531{
532 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
533
534 BT_DBG("%s status 0x%x", hdev->name, rp->status);
535
536 if (!rp->status)
537 bacpy(&hdev->bdaddr, &rp->bdaddr);
538
539 hci_req_complete(hdev, rp->status);
540}
541
542static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
543{
544 BT_DBG("%s status 0x%x", hdev->name, status);
545
546 if (status) {
547 hci_req_complete(hdev, status);
548
549 hci_conn_check_pending(hdev);
550 } else
551 set_bit(HCI_INQUIRY, &hdev->flags);
552}
553
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
555{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200556 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200559 BT_DBG("%s status 0x%x", hdev->name, status);
560
561 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 if (!cp)
563 return;
564
565 hci_dev_lock(hdev);
566
567 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
568
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200569 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
571 if (status) {
572 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200573 if (status != 0x0c || conn->attempt > 2) {
574 conn->state = BT_CLOSED;
575 hci_proto_connect_cfm(conn, status);
576 hci_conn_del(conn);
577 } else
578 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 }
580 } else {
581 if (!conn) {
582 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
583 if (conn) {
584 conn->out = 1;
585 conn->link_mode |= HCI_LM_MASTER;
586 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -0300587 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 }
589 }
590
591 hci_dev_unlock(hdev);
592}
593
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200594static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200596 struct hci_cp_add_sco *cp;
597 struct hci_conn *acl, *sco;
598 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200600 BT_DBG("%s status 0x%x", hdev->name, status);
601
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200602 if (!status)
603 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200605 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
606 if (!cp)
607 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200609 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200611 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100612
613 hci_dev_lock(hdev);
614
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200615 acl = hci_conn_hash_lookup_handle(hdev, handle);
616 if (acl && (sco = acl->link)) {
617 sco->state = BT_CLOSED;
618
619 hci_proto_connect_cfm(sco, status);
620 hci_conn_del(sco);
621 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100622
623 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624}
625
Marcel Holtmannf8558552008-07-14 20:13:49 +0200626static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
627{
628 struct hci_cp_auth_requested *cp;
629 struct hci_conn *conn;
630
631 BT_DBG("%s status 0x%x", hdev->name, status);
632
633 if (!status)
634 return;
635
636 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
637 if (!cp)
638 return;
639
640 hci_dev_lock(hdev);
641
642 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
643 if (conn) {
644 if (conn->state == BT_CONFIG) {
645 hci_proto_connect_cfm(conn, status);
646 hci_conn_put(conn);
647 }
648 }
649
650 hci_dev_unlock(hdev);
651}
652
653static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
654{
655 struct hci_cp_set_conn_encrypt *cp;
656 struct hci_conn *conn;
657
658 BT_DBG("%s status 0x%x", hdev->name, status);
659
660 if (!status)
661 return;
662
663 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
664 if (!cp)
665 return;
666
667 hci_dev_lock(hdev);
668
669 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
670 if (conn) {
671 if (conn->state == BT_CONFIG) {
672 hci_proto_connect_cfm(conn, status);
673 hci_conn_put(conn);
674 }
675 }
676
677 hci_dev_unlock(hdev);
678}
679
Johan Hedberg392599b2010-11-18 22:22:28 +0200680static int hci_request_outgoing_auth(struct hci_dev *hdev,
681 struct hci_conn *conn)
682{
683 struct hci_cp_auth_requested cp;
684
685 if (conn->state != BT_CONFIG || !conn->out)
686 return 0;
687
688 if (conn->sec_level == BT_SECURITY_SDP)
689 return 0;
690
691 /* Only request authentication for SSP connections or non-SSP
692 * devices with sec_level HIGH */
693 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
694 conn->sec_level != BT_SECURITY_HIGH)
695 return 0;
696
697 cp.handle = __cpu_to_le16(conn->handle);
698 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
699
700 return 1;
701}
702
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200703static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
704{
705 BT_DBG("%s status 0x%x", hdev->name, status);
706}
707
Marcel Holtmann769be972008-07-14 20:13:49 +0200708static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
709{
710 struct hci_cp_read_remote_features *cp;
711 struct hci_conn *conn;
712
713 BT_DBG("%s status 0x%x", hdev->name, status);
714
715 if (!status)
716 return;
717
718 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
719 if (!cp)
720 return;
721
722 hci_dev_lock(hdev);
723
724 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
725 if (conn) {
726 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +0200727 hci_proto_connect_cfm(conn, status);
728 hci_conn_put(conn);
729 }
730 }
731
732 hci_dev_unlock(hdev);
733}
734
735static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
736{
737 struct hci_cp_read_remote_ext_features *cp;
738 struct hci_conn *conn;
739
740 BT_DBG("%s status 0x%x", hdev->name, status);
741
742 if (!status)
743 return;
744
745 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
746 if (!cp)
747 return;
748
749 hci_dev_lock(hdev);
750
751 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
752 if (conn) {
753 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +0200754 hci_proto_connect_cfm(conn, status);
755 hci_conn_put(conn);
756 }
757 }
758
759 hci_dev_unlock(hdev);
760}
761
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200762static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
763{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200764 struct hci_cp_setup_sync_conn *cp;
765 struct hci_conn *acl, *sco;
766 __u16 handle;
767
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200768 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200769
770 if (!status)
771 return;
772
773 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
774 if (!cp)
775 return;
776
777 handle = __le16_to_cpu(cp->handle);
778
779 BT_DBG("%s handle %d", hdev->name, handle);
780
781 hci_dev_lock(hdev);
782
783 acl = hci_conn_hash_lookup_handle(hdev, handle);
784 if (acl && (sco = acl->link)) {
785 sco->state = BT_CLOSED;
786
787 hci_proto_connect_cfm(sco, status);
788 hci_conn_del(sco);
789 }
790
791 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200792}
793
794static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
795{
796 struct hci_cp_sniff_mode *cp;
797 struct hci_conn *conn;
798
799 BT_DBG("%s status 0x%x", hdev->name, status);
800
801 if (!status)
802 return;
803
804 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
805 if (!cp)
806 return;
807
808 hci_dev_lock(hdev);
809
810 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400811 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200812 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
813
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400814 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
815 hci_sco_setup(conn, status);
816 }
817
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200818 hci_dev_unlock(hdev);
819}
820
821static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
822{
823 struct hci_cp_exit_sniff_mode *cp;
824 struct hci_conn *conn;
825
826 BT_DBG("%s status 0x%x", hdev->name, status);
827
828 if (!status)
829 return;
830
831 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
832 if (!cp)
833 return;
834
835 hci_dev_lock(hdev);
836
837 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400838 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200839 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
840
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400841 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
842 hci_sco_setup(conn, status);
843 }
844
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200845 hci_dev_unlock(hdev);
846}
847
848static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
849{
850 __u8 status = *((__u8 *) skb->data);
851
852 BT_DBG("%s status %d", hdev->name, status);
853
854 clear_bit(HCI_INQUIRY, &hdev->flags);
855
856 hci_req_complete(hdev, status);
857
858 hci_conn_check_pending(hdev);
859}
860
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
862{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700863 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200864 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 int num_rsp = *((__u8 *) skb->data);
866
867 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
868
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700869 if (!num_rsp)
870 return;
871
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700873
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 for (; num_rsp; num_rsp--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 bacpy(&data.bdaddr, &info->bdaddr);
876 data.pscan_rep_mode = info->pscan_rep_mode;
877 data.pscan_period_mode = info->pscan_period_mode;
878 data.pscan_mode = info->pscan_mode;
879 memcpy(data.dev_class, info->dev_class, 3);
880 data.clock_offset = info->clock_offset;
881 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +0200882 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 info++;
884 hci_inquiry_cache_update(hdev, &data);
885 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700886
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 hci_dev_unlock(hdev);
888}
889
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200890static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200892 struct hci_ev_conn_complete *ev = (void *) skb->data;
893 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200895 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700896
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700898
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200899 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +0200900 if (!conn) {
901 if (ev->link_type != SCO_LINK)
902 goto unlock;
903
904 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
905 if (!conn)
906 goto unlock;
907
908 conn->type = SCO_LINK;
909 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700910
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200911 if (!ev->status) {
912 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +0200913
914 if (conn->type == ACL_LINK) {
915 conn->state = BT_CONFIG;
916 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +0200917 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +0200918 } else
919 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200920
Marcel Holtmann9eba32b2009-08-22 14:19:26 -0700921 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +0200922 hci_conn_add_sysfs(conn);
923
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200924 if (test_bit(HCI_AUTH, &hdev->flags))
925 conn->link_mode |= HCI_LM_AUTH;
926
927 if (test_bit(HCI_ENCRYPT, &hdev->flags))
928 conn->link_mode |= HCI_LM_ENCRYPT;
929
930 /* Get remote features */
931 if (conn->type == ACL_LINK) {
932 struct hci_cp_read_remote_features cp;
933 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +0200934 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
935 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700936 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700937
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200938 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +0200939 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200940 struct hci_cp_change_conn_ptype cp;
941 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +0200942 cp.pkt_type = cpu_to_le16(conn->pkt_type);
943 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
944 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200945 }
946 } else
947 conn->state = BT_CLOSED;
948
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400949 if (conn->type == ACL_LINK)
950 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700951
Marcel Holtmann769be972008-07-14 20:13:49 +0200952 if (ev->status) {
953 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200954 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +0100955 } else if (ev->link_type != ACL_LINK)
956 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200957
958unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200960
961 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962}
963
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
965{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200966 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 int mask = hdev->link_mode;
968
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200969 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
970 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971
972 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
973
Johan Hedbergf0358562010-05-18 13:20:32 +0200974 if ((mask & HCI_LM_ACCEPT) && !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +0200976 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978
979 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200980
Marcel Holtmannc7bdd502008-07-14 20:13:47 +0200981 if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr)))
982 memcpy(ie->data.dev_class, ev->dev_class, 3);
983
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
985 if (!conn) {
986 if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -0300987 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 hci_dev_unlock(hdev);
989 return;
990 }
991 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200992
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 memcpy(conn->dev_class, ev->dev_class, 3);
994 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200995
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996 hci_dev_unlock(hdev);
997
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200998 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
999 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001001 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001003 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1004 cp.role = 0x00; /* Become master */
1005 else
1006 cp.role = 0x01; /* Remain slave */
1007
1008 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1009 sizeof(cp), &cp);
1010 } else {
1011 struct hci_cp_accept_sync_conn_req cp;
1012
1013 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001014 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001015
1016 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1017 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1018 cp.max_latency = cpu_to_le16(0xffff);
1019 cp.content_format = cpu_to_le16(hdev->voice_setting);
1020 cp.retrans_effort = 0xff;
1021
1022 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1023 sizeof(cp), &cp);
1024 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 } else {
1026 /* Connection rejected */
1027 struct hci_cp_reject_conn_req cp;
1028
1029 bacpy(&cp.bdaddr, &ev->bdaddr);
1030 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001031 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 }
1033}
1034
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1036{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001037 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001038 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039
1040 BT_DBG("%s status %d", hdev->name, ev->status);
1041
1042 if (ev->status)
1043 return;
1044
1045 hci_dev_lock(hdev);
1046
Marcel Holtmann04837f62006-07-03 10:02:33 +02001047 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 if (conn) {
1049 conn->state = BT_CLOSED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001050
Marcel Holtmann2950f212009-02-12 14:02:50 +01001051 hci_proto_disconn_cfm(conn, ev->reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 hci_conn_del(conn);
1053 }
1054
1055 hci_dev_unlock(hdev);
1056}
1057
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001058static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1059{
1060 struct hci_ev_auth_complete *ev = (void *) skb->data;
1061 struct hci_conn *conn;
1062
1063 BT_DBG("%s status %d", hdev->name, ev->status);
1064
1065 hci_dev_lock(hdev);
1066
1067 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1068 if (conn) {
1069 if (!ev->status)
1070 conn->link_mode |= HCI_LM_AUTH;
Johan Hedbergda213f42010-06-18 11:08:56 +03001071 else
1072 conn->sec_level = BT_SECURITY_LOW;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001073
1074 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1075
Marcel Holtmannf8558552008-07-14 20:13:49 +02001076 if (conn->state == BT_CONFIG) {
1077 if (!ev->status && hdev->ssp_mode > 0 &&
1078 conn->ssp_mode > 0) {
1079 struct hci_cp_set_conn_encrypt cp;
1080 cp.handle = ev->handle;
1081 cp.encrypt = 0x01;
1082 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1083 sizeof(cp), &cp);
1084 } else {
1085 conn->state = BT_CONNECTED;
1086 hci_proto_connect_cfm(conn, ev->status);
1087 hci_conn_put(conn);
1088 }
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001089 } else {
Marcel Holtmannf8558552008-07-14 20:13:49 +02001090 hci_auth_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001091
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001092 hci_conn_hold(conn);
1093 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1094 hci_conn_put(conn);
1095 }
1096
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001097 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1098 if (!ev->status) {
1099 struct hci_cp_set_conn_encrypt cp;
Marcel Holtmannf8558552008-07-14 20:13:49 +02001100 cp.handle = ev->handle;
1101 cp.encrypt = 0x01;
1102 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1103 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001104 } else {
1105 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1106 hci_encrypt_cfm(conn, ev->status, 0x00);
1107 }
1108 }
1109 }
1110
1111 hci_dev_unlock(hdev);
1112}
1113
1114static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1115{
1116 BT_DBG("%s", hdev->name);
1117
1118 hci_conn_check_pending(hdev);
1119}
1120
1121static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1122{
1123 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1124 struct hci_conn *conn;
1125
1126 BT_DBG("%s status %d", hdev->name, ev->status);
1127
1128 hci_dev_lock(hdev);
1129
1130 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1131 if (conn) {
1132 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001133 if (ev->encrypt) {
1134 /* Encryption implies authentication */
1135 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001136 conn->link_mode |= HCI_LM_ENCRYPT;
Marcel Holtmannae293192008-07-14 20:13:45 +02001137 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001138 conn->link_mode &= ~HCI_LM_ENCRYPT;
1139 }
1140
1141 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1142
Marcel Holtmannf8558552008-07-14 20:13:49 +02001143 if (conn->state == BT_CONFIG) {
1144 if (!ev->status)
1145 conn->state = BT_CONNECTED;
1146
1147 hci_proto_connect_cfm(conn, ev->status);
1148 hci_conn_put(conn);
1149 } else
1150 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001151 }
1152
1153 hci_dev_unlock(hdev);
1154}
1155
1156static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1157{
1158 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1159 struct hci_conn *conn;
1160
1161 BT_DBG("%s status %d", hdev->name, ev->status);
1162
1163 hci_dev_lock(hdev);
1164
1165 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1166 if (conn) {
1167 if (!ev->status)
1168 conn->link_mode |= HCI_LM_SECURE;
1169
1170 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1171
1172 hci_key_change_cfm(conn, ev->status);
1173 }
1174
1175 hci_dev_unlock(hdev);
1176}
1177
1178static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1179{
1180 struct hci_ev_remote_features *ev = (void *) skb->data;
1181 struct hci_conn *conn;
Johan Hedberg392599b2010-11-18 22:22:28 +02001182 int auth_requested;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001183
1184 BT_DBG("%s status %d", hdev->name, ev->status);
1185
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001186 hci_dev_lock(hdev);
1187
1188 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001189 if (!conn)
1190 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001191
Johan Hedbergccd556f2010-11-10 17:11:51 +02001192 if (!ev->status)
1193 memcpy(conn->features, ev->features, 8);
1194
1195 if (conn->state != BT_CONFIG)
1196 goto unlock;
1197
1198 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1199 struct hci_cp_read_remote_ext_features cp;
1200 cp.handle = ev->handle;
1201 cp.page = 0x01;
1202 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001203 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001204 goto unlock;
1205 }
1206
1207 if (!ev->status)
1208 auth_requested = hci_request_outgoing_auth(hdev, conn);
1209 else
1210 auth_requested = 0;
1211
1212 if (!auth_requested) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001213 conn->state = BT_CONNECTED;
1214 hci_proto_connect_cfm(conn, ev->status);
1215 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001216 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001217
Johan Hedbergccd556f2010-11-10 17:11:51 +02001218unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001219 hci_dev_unlock(hdev);
1220}
1221
1222static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1223{
1224 BT_DBG("%s", hdev->name);
1225}
1226
1227static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1228{
1229 BT_DBG("%s", hdev->name);
1230}
1231
1232static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1233{
1234 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1235 __u16 opcode;
1236
1237 skb_pull(skb, sizeof(*ev));
1238
1239 opcode = __le16_to_cpu(ev->opcode);
1240
1241 switch (opcode) {
1242 case HCI_OP_INQUIRY_CANCEL:
1243 hci_cc_inquiry_cancel(hdev, skb);
1244 break;
1245
1246 case HCI_OP_EXIT_PERIODIC_INQ:
1247 hci_cc_exit_periodic_inq(hdev, skb);
1248 break;
1249
1250 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1251 hci_cc_remote_name_req_cancel(hdev, skb);
1252 break;
1253
1254 case HCI_OP_ROLE_DISCOVERY:
1255 hci_cc_role_discovery(hdev, skb);
1256 break;
1257
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001258 case HCI_OP_READ_LINK_POLICY:
1259 hci_cc_read_link_policy(hdev, skb);
1260 break;
1261
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001262 case HCI_OP_WRITE_LINK_POLICY:
1263 hci_cc_write_link_policy(hdev, skb);
1264 break;
1265
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001266 case HCI_OP_READ_DEF_LINK_POLICY:
1267 hci_cc_read_def_link_policy(hdev, skb);
1268 break;
1269
1270 case HCI_OP_WRITE_DEF_LINK_POLICY:
1271 hci_cc_write_def_link_policy(hdev, skb);
1272 break;
1273
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001274 case HCI_OP_RESET:
1275 hci_cc_reset(hdev, skb);
1276 break;
1277
1278 case HCI_OP_WRITE_LOCAL_NAME:
1279 hci_cc_write_local_name(hdev, skb);
1280 break;
1281
1282 case HCI_OP_READ_LOCAL_NAME:
1283 hci_cc_read_local_name(hdev, skb);
1284 break;
1285
1286 case HCI_OP_WRITE_AUTH_ENABLE:
1287 hci_cc_write_auth_enable(hdev, skb);
1288 break;
1289
1290 case HCI_OP_WRITE_ENCRYPT_MODE:
1291 hci_cc_write_encrypt_mode(hdev, skb);
1292 break;
1293
1294 case HCI_OP_WRITE_SCAN_ENABLE:
1295 hci_cc_write_scan_enable(hdev, skb);
1296 break;
1297
1298 case HCI_OP_READ_CLASS_OF_DEV:
1299 hci_cc_read_class_of_dev(hdev, skb);
1300 break;
1301
1302 case HCI_OP_WRITE_CLASS_OF_DEV:
1303 hci_cc_write_class_of_dev(hdev, skb);
1304 break;
1305
1306 case HCI_OP_READ_VOICE_SETTING:
1307 hci_cc_read_voice_setting(hdev, skb);
1308 break;
1309
1310 case HCI_OP_WRITE_VOICE_SETTING:
1311 hci_cc_write_voice_setting(hdev, skb);
1312 break;
1313
1314 case HCI_OP_HOST_BUFFER_SIZE:
1315 hci_cc_host_buffer_size(hdev, skb);
1316 break;
1317
Marcel Holtmann333140b2008-07-14 20:13:48 +02001318 case HCI_OP_READ_SSP_MODE:
1319 hci_cc_read_ssp_mode(hdev, skb);
1320 break;
1321
1322 case HCI_OP_WRITE_SSP_MODE:
1323 hci_cc_write_ssp_mode(hdev, skb);
1324 break;
1325
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001326 case HCI_OP_READ_LOCAL_VERSION:
1327 hci_cc_read_local_version(hdev, skb);
1328 break;
1329
1330 case HCI_OP_READ_LOCAL_COMMANDS:
1331 hci_cc_read_local_commands(hdev, skb);
1332 break;
1333
1334 case HCI_OP_READ_LOCAL_FEATURES:
1335 hci_cc_read_local_features(hdev, skb);
1336 break;
1337
1338 case HCI_OP_READ_BUFFER_SIZE:
1339 hci_cc_read_buffer_size(hdev, skb);
1340 break;
1341
1342 case HCI_OP_READ_BD_ADDR:
1343 hci_cc_read_bd_addr(hdev, skb);
1344 break;
1345
1346 default:
1347 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1348 break;
1349 }
1350
1351 if (ev->ncmd) {
1352 atomic_set(&hdev->cmd_cnt, 1);
1353 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001354 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001355 }
1356}
1357
1358static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1359{
1360 struct hci_ev_cmd_status *ev = (void *) skb->data;
1361 __u16 opcode;
1362
1363 skb_pull(skb, sizeof(*ev));
1364
1365 opcode = __le16_to_cpu(ev->opcode);
1366
1367 switch (opcode) {
1368 case HCI_OP_INQUIRY:
1369 hci_cs_inquiry(hdev, ev->status);
1370 break;
1371
1372 case HCI_OP_CREATE_CONN:
1373 hci_cs_create_conn(hdev, ev->status);
1374 break;
1375
1376 case HCI_OP_ADD_SCO:
1377 hci_cs_add_sco(hdev, ev->status);
1378 break;
1379
Marcel Holtmannf8558552008-07-14 20:13:49 +02001380 case HCI_OP_AUTH_REQUESTED:
1381 hci_cs_auth_requested(hdev, ev->status);
1382 break;
1383
1384 case HCI_OP_SET_CONN_ENCRYPT:
1385 hci_cs_set_conn_encrypt(hdev, ev->status);
1386 break;
1387
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001388 case HCI_OP_REMOTE_NAME_REQ:
1389 hci_cs_remote_name_req(hdev, ev->status);
1390 break;
1391
Marcel Holtmann769be972008-07-14 20:13:49 +02001392 case HCI_OP_READ_REMOTE_FEATURES:
1393 hci_cs_read_remote_features(hdev, ev->status);
1394 break;
1395
1396 case HCI_OP_READ_REMOTE_EXT_FEATURES:
1397 hci_cs_read_remote_ext_features(hdev, ev->status);
1398 break;
1399
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001400 case HCI_OP_SETUP_SYNC_CONN:
1401 hci_cs_setup_sync_conn(hdev, ev->status);
1402 break;
1403
1404 case HCI_OP_SNIFF_MODE:
1405 hci_cs_sniff_mode(hdev, ev->status);
1406 break;
1407
1408 case HCI_OP_EXIT_SNIFF_MODE:
1409 hci_cs_exit_sniff_mode(hdev, ev->status);
1410 break;
1411
1412 default:
1413 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1414 break;
1415 }
1416
1417 if (ev->ncmd) {
1418 atomic_set(&hdev->cmd_cnt, 1);
1419 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001420 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001421 }
1422}
1423
1424static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1425{
1426 struct hci_ev_role_change *ev = (void *) skb->data;
1427 struct hci_conn *conn;
1428
1429 BT_DBG("%s status %d", hdev->name, ev->status);
1430
1431 hci_dev_lock(hdev);
1432
1433 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1434 if (conn) {
1435 if (!ev->status) {
1436 if (ev->role)
1437 conn->link_mode &= ~HCI_LM_MASTER;
1438 else
1439 conn->link_mode |= HCI_LM_MASTER;
1440 }
1441
1442 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1443
1444 hci_role_switch_cfm(conn, ev->status, ev->role);
1445 }
1446
1447 hci_dev_unlock(hdev);
1448}
1449
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
1451{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001452 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001453 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454 int i;
1455
1456 skb_pull(skb, sizeof(*ev));
1457
1458 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
1459
1460 if (skb->len < ev->num_hndl * 4) {
1461 BT_DBG("%s bad parameters", hdev->name);
1462 return;
1463 }
1464
1465 tasklet_disable(&hdev->tx_task);
1466
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001467 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 struct hci_conn *conn;
1469 __u16 handle, count;
1470
Harvey Harrison83985312008-05-02 16:25:46 -07001471 handle = get_unaligned_le16(ptr++);
1472 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473
1474 conn = hci_conn_hash_lookup_handle(hdev, handle);
1475 if (conn) {
1476 conn->sent -= count;
1477
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001478 if (conn->type == ACL_LINK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479 if ((hdev->acl_cnt += count) > hdev->acl_pkts)
1480 hdev->acl_cnt = hdev->acl_pkts;
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001481 } else {
1482 if ((hdev->sco_cnt += count) > hdev->sco_pkts)
1483 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 }
1485 }
1486 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001487
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001488 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489
1490 tasklet_enable(&hdev->tx_task);
1491}
1492
Marcel Holtmann04837f62006-07-03 10:02:33 +02001493static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001495 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001496 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497
1498 BT_DBG("%s status %d", hdev->name, ev->status);
1499
1500 hci_dev_lock(hdev);
1501
Marcel Holtmann04837f62006-07-03 10:02:33 +02001502 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1503 if (conn) {
1504 conn->mode = ev->mode;
1505 conn->interval = __le16_to_cpu(ev->interval);
1506
1507 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
1508 if (conn->mode == HCI_CM_ACTIVE)
1509 conn->power_save = 1;
1510 else
1511 conn->power_save = 0;
1512 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001513
1514 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1515 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001516 }
1517
1518 hci_dev_unlock(hdev);
1519}
1520
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1522{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001523 struct hci_ev_pin_code_req *ev = (void *) skb->data;
1524 struct hci_conn *conn;
1525
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001526 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001527
1528 hci_dev_lock(hdev);
1529
1530 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Marcel Holtmann3d7a9d12009-05-09 12:09:21 -07001531 if (conn && conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001532 hci_conn_hold(conn);
1533 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1534 hci_conn_put(conn);
1535 }
1536
1537 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538}
1539
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1541{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001542 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543}
1544
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
1546{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001547 struct hci_ev_link_key_notify *ev = (void *) skb->data;
1548 struct hci_conn *conn;
1549
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001550 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001551
1552 hci_dev_lock(hdev);
1553
1554 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1555 if (conn) {
1556 hci_conn_hold(conn);
1557 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1558 hci_conn_put(conn);
1559 }
1560
1561 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562}
1563
Marcel Holtmann04837f62006-07-03 10:02:33 +02001564static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
1565{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001566 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001567 struct hci_conn *conn;
1568
1569 BT_DBG("%s status %d", hdev->name, ev->status);
1570
1571 hci_dev_lock(hdev);
1572
1573 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 if (conn && !ev->status) {
1575 struct inquiry_entry *ie;
1576
1577 if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
1578 ie->data.clock_offset = ev->clock_offset;
1579 ie->timestamp = jiffies;
1580 }
1581 }
1582
1583 hci_dev_unlock(hdev);
1584}
1585
Marcel Holtmanna8746412008-07-14 20:13:46 +02001586static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1587{
1588 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
1589 struct hci_conn *conn;
1590
1591 BT_DBG("%s status %d", hdev->name, ev->status);
1592
1593 hci_dev_lock(hdev);
1594
1595 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1596 if (conn && !ev->status)
1597 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
1598
1599 hci_dev_unlock(hdev);
1600}
1601
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001602static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
1603{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001604 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001605 struct inquiry_entry *ie;
1606
1607 BT_DBG("%s", hdev->name);
1608
1609 hci_dev_lock(hdev);
1610
1611 if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) {
1612 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
1613 ie->timestamp = jiffies;
1614 }
1615
1616 hci_dev_unlock(hdev);
1617}
1618
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001619static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
1620{
1621 struct inquiry_data data;
1622 int num_rsp = *((__u8 *) skb->data);
1623
1624 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1625
1626 if (!num_rsp)
1627 return;
1628
1629 hci_dev_lock(hdev);
1630
1631 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
1632 struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);
1633
1634 for (; num_rsp; num_rsp--) {
1635 bacpy(&data.bdaddr, &info->bdaddr);
1636 data.pscan_rep_mode = info->pscan_rep_mode;
1637 data.pscan_period_mode = info->pscan_period_mode;
1638 data.pscan_mode = info->pscan_mode;
1639 memcpy(data.dev_class, info->dev_class, 3);
1640 data.clock_offset = info->clock_offset;
1641 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001642 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001643 info++;
1644 hci_inquiry_cache_update(hdev, &data);
1645 }
1646 } else {
1647 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
1648
1649 for (; num_rsp; num_rsp--) {
1650 bacpy(&data.bdaddr, &info->bdaddr);
1651 data.pscan_rep_mode = info->pscan_rep_mode;
1652 data.pscan_period_mode = info->pscan_period_mode;
1653 data.pscan_mode = 0x00;
1654 memcpy(data.dev_class, info->dev_class, 3);
1655 data.clock_offset = info->clock_offset;
1656 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001657 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001658 info++;
1659 hci_inquiry_cache_update(hdev, &data);
1660 }
1661 }
1662
1663 hci_dev_unlock(hdev);
1664}
1665
1666static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1667{
Marcel Holtmann41a96212008-07-14 20:13:48 +02001668 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
1669 struct hci_conn *conn;
Johan Hedberg392599b2010-11-18 22:22:28 +02001670 int auth_requested;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001671
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001672 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02001673
Marcel Holtmann41a96212008-07-14 20:13:48 +02001674 hci_dev_lock(hdev);
1675
1676 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001677 if (!conn)
1678 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001679
Johan Hedbergccd556f2010-11-10 17:11:51 +02001680 if (!ev->status && ev->page == 0x01) {
1681 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001682
Johan Hedbergccd556f2010-11-10 17:11:51 +02001683 if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst)))
1684 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02001685
Johan Hedbergccd556f2010-11-10 17:11:51 +02001686 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02001687 }
1688
Johan Hedbergccd556f2010-11-10 17:11:51 +02001689 if (conn->state != BT_CONFIG)
1690 goto unlock;
1691
Johan Hedberg392599b2010-11-18 22:22:28 +02001692 if (!ev->status)
1693 auth_requested = hci_request_outgoing_auth(hdev, conn);
1694 else
1695 auth_requested = 0;
1696
1697 if (!auth_requested) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001698 conn->state = BT_CONNECTED;
1699 hci_proto_connect_cfm(conn, ev->status);
1700 hci_conn_put(conn);
1701 }
1702
1703unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02001704 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001705}
1706
1707static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1708{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001709 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
1710 struct hci_conn *conn;
1711
1712 BT_DBG("%s status %d", hdev->name, ev->status);
1713
1714 hci_dev_lock(hdev);
1715
1716 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02001717 if (!conn) {
1718 if (ev->link_type == ESCO_LINK)
1719 goto unlock;
1720
1721 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1722 if (!conn)
1723 goto unlock;
1724
1725 conn->type = SCO_LINK;
1726 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001727
Marcel Holtmann732547f2009-04-19 19:14:14 +02001728 switch (ev->status) {
1729 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001730 conn->handle = __le16_to_cpu(ev->handle);
1731 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001732
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001733 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001734 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02001735 break;
1736
Stephen Coe705e5712010-02-16 11:29:44 -05001737 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02001738 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08001739 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02001740 case 0x1f: /* Unspecified error */
1741 if (conn->out && conn->attempt < 2) {
1742 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
1743 (hdev->esco_type & EDR_ESCO_MASK);
1744 hci_setup_sync(conn, conn->link->handle);
1745 goto unlock;
1746 }
1747 /* fall through */
1748
1749 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001750 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02001751 break;
1752 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001753
1754 hci_proto_connect_cfm(conn, ev->status);
1755 if (ev->status)
1756 hci_conn_del(conn);
1757
1758unlock:
1759 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001760}
1761
1762static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
1763{
1764 BT_DBG("%s", hdev->name);
1765}
1766
Marcel Holtmann04837f62006-07-03 10:02:33 +02001767static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
1768{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001769 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001770 struct hci_conn *conn;
1771
1772 BT_DBG("%s status %d", hdev->name, ev->status);
1773
1774 hci_dev_lock(hdev);
1775
1776 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1777 if (conn) {
1778 }
1779
1780 hci_dev_unlock(hdev);
1781}
1782
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001783static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1784{
1785 struct inquiry_data data;
1786 struct extended_inquiry_info *info = (void *) (skb->data + 1);
1787 int num_rsp = *((__u8 *) skb->data);
1788
1789 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1790
1791 if (!num_rsp)
1792 return;
1793
1794 hci_dev_lock(hdev);
1795
1796 for (; num_rsp; num_rsp--) {
1797 bacpy(&data.bdaddr, &info->bdaddr);
1798 data.pscan_rep_mode = info->pscan_rep_mode;
1799 data.pscan_period_mode = info->pscan_period_mode;
1800 data.pscan_mode = 0x00;
1801 memcpy(data.dev_class, info->dev_class, 3);
1802 data.clock_offset = info->clock_offset;
1803 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001804 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001805 info++;
1806 hci_inquiry_cache_update(hdev, &data);
1807 }
1808
1809 hci_dev_unlock(hdev);
1810}
1811
Marcel Holtmann04936842008-07-14 20:13:48 +02001812static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1813{
1814 struct hci_ev_io_capa_request *ev = (void *) skb->data;
1815 struct hci_conn *conn;
1816
1817 BT_DBG("%s", hdev->name);
1818
1819 hci_dev_lock(hdev);
1820
1821 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1822 if (conn)
1823 hci_conn_hold(conn);
1824
1825 hci_dev_unlock(hdev);
1826}
1827
1828static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1829{
1830 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
1831 struct hci_conn *conn;
1832
1833 BT_DBG("%s", hdev->name);
1834
1835 hci_dev_lock(hdev);
1836
1837 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1838 if (conn)
1839 hci_conn_put(conn);
1840
1841 hci_dev_unlock(hdev);
1842}
1843
Marcel Holtmann41a96212008-07-14 20:13:48 +02001844static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1845{
1846 struct hci_ev_remote_host_features *ev = (void *) skb->data;
1847 struct inquiry_entry *ie;
1848
1849 BT_DBG("%s", hdev->name);
1850
1851 hci_dev_lock(hdev);
1852
1853 if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr)))
1854 ie->data.ssp_mode = (ev->features[0] & 0x01);
1855
1856 hci_dev_unlock(hdev);
1857}
1858
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
1860{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001861 struct hci_event_hdr *hdr = (void *) skb->data;
1862 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863
1864 skb_pull(skb, HCI_EVENT_HDR_SIZE);
1865
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001866 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 case HCI_EV_INQUIRY_COMPLETE:
1868 hci_inquiry_complete_evt(hdev, skb);
1869 break;
1870
1871 case HCI_EV_INQUIRY_RESULT:
1872 hci_inquiry_result_evt(hdev, skb);
1873 break;
1874
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001875 case HCI_EV_CONN_COMPLETE:
1876 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02001877 break;
1878
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 case HCI_EV_CONN_REQUEST:
1880 hci_conn_request_evt(hdev, skb);
1881 break;
1882
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883 case HCI_EV_DISCONN_COMPLETE:
1884 hci_disconn_complete_evt(hdev, skb);
1885 break;
1886
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 case HCI_EV_AUTH_COMPLETE:
1888 hci_auth_complete_evt(hdev, skb);
1889 break;
1890
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001891 case HCI_EV_REMOTE_NAME:
1892 hci_remote_name_evt(hdev, skb);
1893 break;
1894
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 case HCI_EV_ENCRYPT_CHANGE:
1896 hci_encrypt_change_evt(hdev, skb);
1897 break;
1898
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001899 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
1900 hci_change_link_key_complete_evt(hdev, skb);
1901 break;
1902
1903 case HCI_EV_REMOTE_FEATURES:
1904 hci_remote_features_evt(hdev, skb);
1905 break;
1906
1907 case HCI_EV_REMOTE_VERSION:
1908 hci_remote_version_evt(hdev, skb);
1909 break;
1910
1911 case HCI_EV_QOS_SETUP_COMPLETE:
1912 hci_qos_setup_complete_evt(hdev, skb);
1913 break;
1914
1915 case HCI_EV_CMD_COMPLETE:
1916 hci_cmd_complete_evt(hdev, skb);
1917 break;
1918
1919 case HCI_EV_CMD_STATUS:
1920 hci_cmd_status_evt(hdev, skb);
1921 break;
1922
1923 case HCI_EV_ROLE_CHANGE:
1924 hci_role_change_evt(hdev, skb);
1925 break;
1926
1927 case HCI_EV_NUM_COMP_PKTS:
1928 hci_num_comp_pkts_evt(hdev, skb);
1929 break;
1930
1931 case HCI_EV_MODE_CHANGE:
1932 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933 break;
1934
1935 case HCI_EV_PIN_CODE_REQ:
1936 hci_pin_code_request_evt(hdev, skb);
1937 break;
1938
1939 case HCI_EV_LINK_KEY_REQ:
1940 hci_link_key_request_evt(hdev, skb);
1941 break;
1942
1943 case HCI_EV_LINK_KEY_NOTIFY:
1944 hci_link_key_notify_evt(hdev, skb);
1945 break;
1946
1947 case HCI_EV_CLOCK_OFFSET:
1948 hci_clock_offset_evt(hdev, skb);
1949 break;
1950
Marcel Holtmanna8746412008-07-14 20:13:46 +02001951 case HCI_EV_PKT_TYPE_CHANGE:
1952 hci_pkt_type_change_evt(hdev, skb);
1953 break;
1954
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001955 case HCI_EV_PSCAN_REP_MODE:
1956 hci_pscan_rep_mode_evt(hdev, skb);
1957 break;
1958
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001959 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
1960 hci_inquiry_result_with_rssi_evt(hdev, skb);
1961 break;
1962
1963 case HCI_EV_REMOTE_EXT_FEATURES:
1964 hci_remote_ext_features_evt(hdev, skb);
1965 break;
1966
1967 case HCI_EV_SYNC_CONN_COMPLETE:
1968 hci_sync_conn_complete_evt(hdev, skb);
1969 break;
1970
1971 case HCI_EV_SYNC_CONN_CHANGED:
1972 hci_sync_conn_changed_evt(hdev, skb);
1973 break;
1974
Marcel Holtmann04837f62006-07-03 10:02:33 +02001975 case HCI_EV_SNIFF_SUBRATE:
1976 hci_sniff_subrate_evt(hdev, skb);
1977 break;
1978
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001979 case HCI_EV_EXTENDED_INQUIRY_RESULT:
1980 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981 break;
1982
Marcel Holtmann04936842008-07-14 20:13:48 +02001983 case HCI_EV_IO_CAPA_REQUEST:
1984 hci_io_capa_request_evt(hdev, skb);
1985 break;
1986
1987 case HCI_EV_SIMPLE_PAIR_COMPLETE:
1988 hci_simple_pair_complete_evt(hdev, skb);
1989 break;
1990
Marcel Holtmann41a96212008-07-14 20:13:48 +02001991 case HCI_EV_REMOTE_HOST_FEATURES:
1992 hci_remote_host_features_evt(hdev, skb);
1993 break;
1994
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001995 default:
1996 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997 break;
1998 }
1999
2000 kfree_skb(skb);
2001 hdev->stat.evt_rx++;
2002}
2003
2004/* Generate internal stack event */
2005void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
2006{
2007 struct hci_event_hdr *hdr;
2008 struct hci_ev_stack_internal *ev;
2009 struct sk_buff *skb;
2010
2011 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
2012 if (!skb)
2013 return;
2014
2015 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
2016 hdr->evt = HCI_EV_STACK_INTERNAL;
2017 hdr->plen = sizeof(*ev) + dlen;
2018
2019 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
2020 ev->type = type;
2021 memcpy(ev->data, data, dlen);
2022
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002023 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07002024 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002025
Marcel Holtmann0d48d932005-08-09 20:30:28 -07002026 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027 skb->dev = (void *) hdev;
2028 hci_send_to_sock(hdev, skb);
2029 kfree_skb(skb);
2030}