blob: a290854fdaa6ac68bba2443a51763723d5be7f62 [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>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020042#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#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
Johan Hedberg23bb5762010-12-21 23:01:27 +020061 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, 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
Johan Hedberg23bb5762010-12-21 23:01:27 +0200177 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200178}
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
Johan Hedberg23bb5762010-12-21 23:01:27 +0200186 hci_req_complete(hdev, HCI_OP_RESET, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200187}
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
Johan Hedberg23bb5762010-12-21 23:01:27 +0200238 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200239}
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
Johan Hedberg23bb5762010-12-21 23:01:27 +0200261 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200262}
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
Johan Hedberg23bb5762010-12-21 23:01:27 +0200288 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200289}
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
Johan Hedberg23bb5762010-12-21 23:01:27 +0200386 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, 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
Johan Hedberg23bb5762010-12-21 23:01:27 +0200539 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
540}
541
542static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
543{
544 __u8 status = *((__u8 *) skb->data);
545
546 BT_DBG("%s status 0x%x", hdev->name, status);
547
548 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200549}
550
551static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
552{
553 BT_DBG("%s status 0x%x", hdev->name, status);
554
555 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +0200556 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200557
558 hci_conn_check_pending(hdev);
559 } else
560 set_bit(HCI_INQUIRY, &hdev->flags);
561}
562
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
564{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200565 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200568 BT_DBG("%s status 0x%x", hdev->name, status);
569
570 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 if (!cp)
572 return;
573
574 hci_dev_lock(hdev);
575
576 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
577
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200578 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579
580 if (status) {
581 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200582 if (status != 0x0c || conn->attempt > 2) {
583 conn->state = BT_CLOSED;
584 hci_proto_connect_cfm(conn, status);
585 hci_conn_del(conn);
586 } else
587 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 }
589 } else {
590 if (!conn) {
591 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
592 if (conn) {
593 conn->out = 1;
594 conn->link_mode |= HCI_LM_MASTER;
595 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -0300596 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 }
598 }
599
600 hci_dev_unlock(hdev);
601}
602
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200603static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200605 struct hci_cp_add_sco *cp;
606 struct hci_conn *acl, *sco;
607 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200609 BT_DBG("%s status 0x%x", hdev->name, status);
610
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200611 if (!status)
612 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200614 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
615 if (!cp)
616 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200618 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200620 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100621
622 hci_dev_lock(hdev);
623
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200624 acl = hci_conn_hash_lookup_handle(hdev, handle);
625 if (acl && (sco = acl->link)) {
626 sco->state = BT_CLOSED;
627
628 hci_proto_connect_cfm(sco, status);
629 hci_conn_del(sco);
630 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100631
632 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633}
634
Marcel Holtmannf8558552008-07-14 20:13:49 +0200635static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
636{
637 struct hci_cp_auth_requested *cp;
638 struct hci_conn *conn;
639
640 BT_DBG("%s status 0x%x", hdev->name, status);
641
642 if (!status)
643 return;
644
645 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
646 if (!cp)
647 return;
648
649 hci_dev_lock(hdev);
650
651 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
652 if (conn) {
653 if (conn->state == BT_CONFIG) {
654 hci_proto_connect_cfm(conn, status);
655 hci_conn_put(conn);
656 }
657 }
658
659 hci_dev_unlock(hdev);
660}
661
662static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
663{
664 struct hci_cp_set_conn_encrypt *cp;
665 struct hci_conn *conn;
666
667 BT_DBG("%s status 0x%x", hdev->name, status);
668
669 if (!status)
670 return;
671
672 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
673 if (!cp)
674 return;
675
676 hci_dev_lock(hdev);
677
678 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
679 if (conn) {
680 if (conn->state == BT_CONFIG) {
681 hci_proto_connect_cfm(conn, status);
682 hci_conn_put(conn);
683 }
684 }
685
686 hci_dev_unlock(hdev);
687}
688
Johan Hedberg127178d2010-11-18 22:22:29 +0200689static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Johan Hedberg392599b2010-11-18 22:22:28 +0200690 struct hci_conn *conn)
691{
Johan Hedberg392599b2010-11-18 22:22:28 +0200692 if (conn->state != BT_CONFIG || !conn->out)
693 return 0;
694
Johan Hedberg765c2a92011-01-19 12:06:52 +0530695 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +0200696 return 0;
697
698 /* Only request authentication for SSP connections or non-SSP
699 * devices with sec_level HIGH */
700 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Johan Hedberg765c2a92011-01-19 12:06:52 +0530701 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +0200702 return 0;
703
Johan Hedberg392599b2010-11-18 22:22:28 +0200704 return 1;
705}
706
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200707static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
708{
Johan Hedberg127178d2010-11-18 22:22:29 +0200709 struct hci_cp_remote_name_req *cp;
710 struct hci_conn *conn;
711
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200712 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +0200713
714 /* If successful wait for the name req complete event before
715 * checking for the need to do authentication */
716 if (!status)
717 return;
718
719 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
720 if (!cp)
721 return;
722
723 hci_dev_lock(hdev);
724
725 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
726 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
727 struct hci_cp_auth_requested cp;
728 cp.handle = __cpu_to_le16(conn->handle);
729 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
730 }
731
732 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200733}
734
Marcel Holtmann769be972008-07-14 20:13:49 +0200735static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
736{
737 struct hci_cp_read_remote_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_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
762static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
763{
764 struct hci_cp_read_remote_ext_features *cp;
765 struct hci_conn *conn;
766
767 BT_DBG("%s status 0x%x", hdev->name, status);
768
769 if (!status)
770 return;
771
772 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
773 if (!cp)
774 return;
775
776 hci_dev_lock(hdev);
777
778 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
779 if (conn) {
780 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +0200781 hci_proto_connect_cfm(conn, status);
782 hci_conn_put(conn);
783 }
784 }
785
786 hci_dev_unlock(hdev);
787}
788
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200789static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
790{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200791 struct hci_cp_setup_sync_conn *cp;
792 struct hci_conn *acl, *sco;
793 __u16 handle;
794
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200795 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200796
797 if (!status)
798 return;
799
800 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
801 if (!cp)
802 return;
803
804 handle = __le16_to_cpu(cp->handle);
805
806 BT_DBG("%s handle %d", hdev->name, handle);
807
808 hci_dev_lock(hdev);
809
810 acl = hci_conn_hash_lookup_handle(hdev, handle);
811 if (acl && (sco = acl->link)) {
812 sco->state = BT_CLOSED;
813
814 hci_proto_connect_cfm(sco, status);
815 hci_conn_del(sco);
816 }
817
818 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200819}
820
821static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
822{
823 struct hci_cp_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_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 void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
849{
850 struct hci_cp_exit_sniff_mode *cp;
851 struct hci_conn *conn;
852
853 BT_DBG("%s status 0x%x", hdev->name, status);
854
855 if (!status)
856 return;
857
858 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
859 if (!cp)
860 return;
861
862 hci_dev_lock(hdev);
863
864 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400865 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200866 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
867
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400868 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
869 hci_sco_setup(conn, status);
870 }
871
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200872 hci_dev_unlock(hdev);
873}
874
875static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
876{
877 __u8 status = *((__u8 *) skb->data);
878
879 BT_DBG("%s status %d", hdev->name, status);
880
881 clear_bit(HCI_INQUIRY, &hdev->flags);
882
Johan Hedberg23bb5762010-12-21 23:01:27 +0200883 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200884
885 hci_conn_check_pending(hdev);
886}
887
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
889{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700890 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200891 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892 int num_rsp = *((__u8 *) skb->data);
893
894 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
895
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700896 if (!num_rsp)
897 return;
898
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700900
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 for (; num_rsp; num_rsp--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 bacpy(&data.bdaddr, &info->bdaddr);
903 data.pscan_rep_mode = info->pscan_rep_mode;
904 data.pscan_period_mode = info->pscan_period_mode;
905 data.pscan_mode = info->pscan_mode;
906 memcpy(data.dev_class, info->dev_class, 3);
907 data.clock_offset = info->clock_offset;
908 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +0200909 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 info++;
911 hci_inquiry_cache_update(hdev, &data);
912 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700913
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 hci_dev_unlock(hdev);
915}
916
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200917static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200919 struct hci_ev_conn_complete *ev = (void *) skb->data;
920 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200922 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700923
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700925
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200926 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +0200927 if (!conn) {
928 if (ev->link_type != SCO_LINK)
929 goto unlock;
930
931 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
932 if (!conn)
933 goto unlock;
934
935 conn->type = SCO_LINK;
936 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700937
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200938 if (!ev->status) {
939 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +0200940
941 if (conn->type == ACL_LINK) {
942 conn->state = BT_CONFIG;
943 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +0200944 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +0200945 } else
946 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200947
Marcel Holtmann9eba32b2009-08-22 14:19:26 -0700948 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +0200949 hci_conn_add_sysfs(conn);
950
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200951 if (test_bit(HCI_AUTH, &hdev->flags))
952 conn->link_mode |= HCI_LM_AUTH;
953
954 if (test_bit(HCI_ENCRYPT, &hdev->flags))
955 conn->link_mode |= HCI_LM_ENCRYPT;
956
957 /* Get remote features */
958 if (conn->type == ACL_LINK) {
959 struct hci_cp_read_remote_features cp;
960 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +0200961 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
962 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700963 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700964
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200965 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +0200966 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200967 struct hci_cp_change_conn_ptype cp;
968 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +0200969 cp.pkt_type = cpu_to_le16(conn->pkt_type);
970 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
971 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200972 }
973 } else
974 conn->state = BT_CLOSED;
975
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400976 if (conn->type == ACL_LINK)
977 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700978
Marcel Holtmann769be972008-07-14 20:13:49 +0200979 if (ev->status) {
980 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200981 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +0100982 } else if (ev->link_type != ACL_LINK)
983 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200984
985unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200987
988 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989}
990
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
992{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200993 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994 int mask = hdev->link_mode;
995
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200996 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
997 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998
999 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1000
Johan Hedbergf0358562010-05-18 13:20:32 +02001001 if ((mask & HCI_LM_ACCEPT) && !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001003 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005
1006 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001007
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001008 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1009 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001010 memcpy(ie->data.dev_class, ev->dev_class, 3);
1011
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1013 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001014 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1015 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001016 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017 hci_dev_unlock(hdev);
1018 return;
1019 }
1020 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001021
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 memcpy(conn->dev_class, ev->dev_class, 3);
1023 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001024
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 hci_dev_unlock(hdev);
1026
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001027 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1028 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001030 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001032 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1033 cp.role = 0x00; /* Become master */
1034 else
1035 cp.role = 0x01; /* Remain slave */
1036
1037 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1038 sizeof(cp), &cp);
1039 } else {
1040 struct hci_cp_accept_sync_conn_req cp;
1041
1042 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001043 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001044
1045 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1046 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1047 cp.max_latency = cpu_to_le16(0xffff);
1048 cp.content_format = cpu_to_le16(hdev->voice_setting);
1049 cp.retrans_effort = 0xff;
1050
1051 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1052 sizeof(cp), &cp);
1053 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 } else {
1055 /* Connection rejected */
1056 struct hci_cp_reject_conn_req cp;
1057
1058 bacpy(&cp.bdaddr, &ev->bdaddr);
1059 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001060 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061 }
1062}
1063
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1065{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001066 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001067 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
1069 BT_DBG("%s status %d", hdev->name, ev->status);
1070
1071 if (ev->status)
1072 return;
1073
1074 hci_dev_lock(hdev);
1075
Marcel Holtmann04837f62006-07-03 10:02:33 +02001076 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 if (conn) {
1078 conn->state = BT_CLOSED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001079
Marcel Holtmann2950f212009-02-12 14:02:50 +01001080 hci_proto_disconn_cfm(conn, ev->reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 hci_conn_del(conn);
1082 }
1083
1084 hci_dev_unlock(hdev);
1085}
1086
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001087static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1088{
1089 struct hci_ev_auth_complete *ev = (void *) skb->data;
1090 struct hci_conn *conn;
1091
1092 BT_DBG("%s status %d", hdev->name, ev->status);
1093
1094 hci_dev_lock(hdev);
1095
1096 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1097 if (conn) {
Johan Hedberg765c2a92011-01-19 12:06:52 +05301098 if (!ev->status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001099 conn->link_mode |= HCI_LM_AUTH;
Johan Hedberg765c2a92011-01-19 12:06:52 +05301100 conn->sec_level = conn->pending_sec_level;
1101 } else
Johan Hedbergda213f42010-06-18 11:08:56 +03001102 conn->sec_level = BT_SECURITY_LOW;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001103
1104 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1105
Marcel Holtmannf8558552008-07-14 20:13:49 +02001106 if (conn->state == BT_CONFIG) {
1107 if (!ev->status && hdev->ssp_mode > 0 &&
1108 conn->ssp_mode > 0) {
1109 struct hci_cp_set_conn_encrypt cp;
1110 cp.handle = ev->handle;
1111 cp.encrypt = 0x01;
1112 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1113 sizeof(cp), &cp);
1114 } else {
1115 conn->state = BT_CONNECTED;
1116 hci_proto_connect_cfm(conn, ev->status);
1117 hci_conn_put(conn);
1118 }
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001119 } else {
Marcel Holtmannf8558552008-07-14 20:13:49 +02001120 hci_auth_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001121
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001122 hci_conn_hold(conn);
1123 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1124 hci_conn_put(conn);
1125 }
1126
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001127 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1128 if (!ev->status) {
1129 struct hci_cp_set_conn_encrypt cp;
Marcel Holtmannf8558552008-07-14 20:13:49 +02001130 cp.handle = ev->handle;
1131 cp.encrypt = 0x01;
1132 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1133 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001134 } else {
1135 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1136 hci_encrypt_cfm(conn, ev->status, 0x00);
1137 }
1138 }
1139 }
1140
1141 hci_dev_unlock(hdev);
1142}
1143
1144static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1145{
Johan Hedberg127178d2010-11-18 22:22:29 +02001146 struct hci_ev_remote_name *ev = (void *) skb->data;
1147 struct hci_conn *conn;
1148
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001149 BT_DBG("%s", hdev->name);
1150
1151 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001152
1153 hci_dev_lock(hdev);
1154
1155 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1156 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1157 struct hci_cp_auth_requested cp;
1158 cp.handle = __cpu_to_le16(conn->handle);
1159 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1160 }
1161
1162 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001163}
1164
1165static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1166{
1167 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1168 struct hci_conn *conn;
1169
1170 BT_DBG("%s status %d", hdev->name, ev->status);
1171
1172 hci_dev_lock(hdev);
1173
1174 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1175 if (conn) {
1176 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001177 if (ev->encrypt) {
1178 /* Encryption implies authentication */
1179 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001180 conn->link_mode |= HCI_LM_ENCRYPT;
Marcel Holtmannae293192008-07-14 20:13:45 +02001181 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001182 conn->link_mode &= ~HCI_LM_ENCRYPT;
1183 }
1184
1185 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1186
Marcel Holtmannf8558552008-07-14 20:13:49 +02001187 if (conn->state == BT_CONFIG) {
1188 if (!ev->status)
1189 conn->state = BT_CONNECTED;
1190
1191 hci_proto_connect_cfm(conn, ev->status);
1192 hci_conn_put(conn);
1193 } else
1194 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001195 }
1196
1197 hci_dev_unlock(hdev);
1198}
1199
1200static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1201{
1202 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1203 struct hci_conn *conn;
1204
1205 BT_DBG("%s status %d", hdev->name, ev->status);
1206
1207 hci_dev_lock(hdev);
1208
1209 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1210 if (conn) {
1211 if (!ev->status)
1212 conn->link_mode |= HCI_LM_SECURE;
1213
1214 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1215
1216 hci_key_change_cfm(conn, ev->status);
1217 }
1218
1219 hci_dev_unlock(hdev);
1220}
1221
1222static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1223{
1224 struct hci_ev_remote_features *ev = (void *) skb->data;
1225 struct hci_conn *conn;
1226
1227 BT_DBG("%s status %d", hdev->name, ev->status);
1228
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001229 hci_dev_lock(hdev);
1230
1231 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001232 if (!conn)
1233 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001234
Johan Hedbergccd556f2010-11-10 17:11:51 +02001235 if (!ev->status)
1236 memcpy(conn->features, ev->features, 8);
1237
1238 if (conn->state != BT_CONFIG)
1239 goto unlock;
1240
1241 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1242 struct hci_cp_read_remote_ext_features cp;
1243 cp.handle = ev->handle;
1244 cp.page = 0x01;
1245 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001246 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001247 goto unlock;
1248 }
1249
Johan Hedberg127178d2010-11-18 22:22:29 +02001250 if (!ev->status) {
1251 struct hci_cp_remote_name_req cp;
1252 memset(&cp, 0, sizeof(cp));
1253 bacpy(&cp.bdaddr, &conn->dst);
1254 cp.pscan_rep_mode = 0x02;
1255 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1256 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001257
Johan Hedberg127178d2010-11-18 22:22:29 +02001258 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001259 conn->state = BT_CONNECTED;
1260 hci_proto_connect_cfm(conn, ev->status);
1261 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001262 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001263
Johan Hedbergccd556f2010-11-10 17:11:51 +02001264unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001265 hci_dev_unlock(hdev);
1266}
1267
1268static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1269{
1270 BT_DBG("%s", hdev->name);
1271}
1272
1273static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1274{
1275 BT_DBG("%s", hdev->name);
1276}
1277
1278static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1279{
1280 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1281 __u16 opcode;
1282
1283 skb_pull(skb, sizeof(*ev));
1284
1285 opcode = __le16_to_cpu(ev->opcode);
1286
1287 switch (opcode) {
1288 case HCI_OP_INQUIRY_CANCEL:
1289 hci_cc_inquiry_cancel(hdev, skb);
1290 break;
1291
1292 case HCI_OP_EXIT_PERIODIC_INQ:
1293 hci_cc_exit_periodic_inq(hdev, skb);
1294 break;
1295
1296 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1297 hci_cc_remote_name_req_cancel(hdev, skb);
1298 break;
1299
1300 case HCI_OP_ROLE_DISCOVERY:
1301 hci_cc_role_discovery(hdev, skb);
1302 break;
1303
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001304 case HCI_OP_READ_LINK_POLICY:
1305 hci_cc_read_link_policy(hdev, skb);
1306 break;
1307
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001308 case HCI_OP_WRITE_LINK_POLICY:
1309 hci_cc_write_link_policy(hdev, skb);
1310 break;
1311
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001312 case HCI_OP_READ_DEF_LINK_POLICY:
1313 hci_cc_read_def_link_policy(hdev, skb);
1314 break;
1315
1316 case HCI_OP_WRITE_DEF_LINK_POLICY:
1317 hci_cc_write_def_link_policy(hdev, skb);
1318 break;
1319
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001320 case HCI_OP_RESET:
1321 hci_cc_reset(hdev, skb);
1322 break;
1323
1324 case HCI_OP_WRITE_LOCAL_NAME:
1325 hci_cc_write_local_name(hdev, skb);
1326 break;
1327
1328 case HCI_OP_READ_LOCAL_NAME:
1329 hci_cc_read_local_name(hdev, skb);
1330 break;
1331
1332 case HCI_OP_WRITE_AUTH_ENABLE:
1333 hci_cc_write_auth_enable(hdev, skb);
1334 break;
1335
1336 case HCI_OP_WRITE_ENCRYPT_MODE:
1337 hci_cc_write_encrypt_mode(hdev, skb);
1338 break;
1339
1340 case HCI_OP_WRITE_SCAN_ENABLE:
1341 hci_cc_write_scan_enable(hdev, skb);
1342 break;
1343
1344 case HCI_OP_READ_CLASS_OF_DEV:
1345 hci_cc_read_class_of_dev(hdev, skb);
1346 break;
1347
1348 case HCI_OP_WRITE_CLASS_OF_DEV:
1349 hci_cc_write_class_of_dev(hdev, skb);
1350 break;
1351
1352 case HCI_OP_READ_VOICE_SETTING:
1353 hci_cc_read_voice_setting(hdev, skb);
1354 break;
1355
1356 case HCI_OP_WRITE_VOICE_SETTING:
1357 hci_cc_write_voice_setting(hdev, skb);
1358 break;
1359
1360 case HCI_OP_HOST_BUFFER_SIZE:
1361 hci_cc_host_buffer_size(hdev, skb);
1362 break;
1363
Marcel Holtmann333140b2008-07-14 20:13:48 +02001364 case HCI_OP_READ_SSP_MODE:
1365 hci_cc_read_ssp_mode(hdev, skb);
1366 break;
1367
1368 case HCI_OP_WRITE_SSP_MODE:
1369 hci_cc_write_ssp_mode(hdev, skb);
1370 break;
1371
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001372 case HCI_OP_READ_LOCAL_VERSION:
1373 hci_cc_read_local_version(hdev, skb);
1374 break;
1375
1376 case HCI_OP_READ_LOCAL_COMMANDS:
1377 hci_cc_read_local_commands(hdev, skb);
1378 break;
1379
1380 case HCI_OP_READ_LOCAL_FEATURES:
1381 hci_cc_read_local_features(hdev, skb);
1382 break;
1383
1384 case HCI_OP_READ_BUFFER_SIZE:
1385 hci_cc_read_buffer_size(hdev, skb);
1386 break;
1387
1388 case HCI_OP_READ_BD_ADDR:
1389 hci_cc_read_bd_addr(hdev, skb);
1390 break;
1391
Johan Hedberg23bb5762010-12-21 23:01:27 +02001392 case HCI_OP_WRITE_CA_TIMEOUT:
1393 hci_cc_write_ca_timeout(hdev, skb);
1394 break;
1395
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001396 default:
1397 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1398 break;
1399 }
1400
1401 if (ev->ncmd) {
1402 atomic_set(&hdev->cmd_cnt, 1);
1403 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001404 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001405 }
1406}
1407
1408static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1409{
1410 struct hci_ev_cmd_status *ev = (void *) skb->data;
1411 __u16 opcode;
1412
1413 skb_pull(skb, sizeof(*ev));
1414
1415 opcode = __le16_to_cpu(ev->opcode);
1416
1417 switch (opcode) {
1418 case HCI_OP_INQUIRY:
1419 hci_cs_inquiry(hdev, ev->status);
1420 break;
1421
1422 case HCI_OP_CREATE_CONN:
1423 hci_cs_create_conn(hdev, ev->status);
1424 break;
1425
1426 case HCI_OP_ADD_SCO:
1427 hci_cs_add_sco(hdev, ev->status);
1428 break;
1429
Marcel Holtmannf8558552008-07-14 20:13:49 +02001430 case HCI_OP_AUTH_REQUESTED:
1431 hci_cs_auth_requested(hdev, ev->status);
1432 break;
1433
1434 case HCI_OP_SET_CONN_ENCRYPT:
1435 hci_cs_set_conn_encrypt(hdev, ev->status);
1436 break;
1437
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001438 case HCI_OP_REMOTE_NAME_REQ:
1439 hci_cs_remote_name_req(hdev, ev->status);
1440 break;
1441
Marcel Holtmann769be972008-07-14 20:13:49 +02001442 case HCI_OP_READ_REMOTE_FEATURES:
1443 hci_cs_read_remote_features(hdev, ev->status);
1444 break;
1445
1446 case HCI_OP_READ_REMOTE_EXT_FEATURES:
1447 hci_cs_read_remote_ext_features(hdev, ev->status);
1448 break;
1449
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001450 case HCI_OP_SETUP_SYNC_CONN:
1451 hci_cs_setup_sync_conn(hdev, ev->status);
1452 break;
1453
1454 case HCI_OP_SNIFF_MODE:
1455 hci_cs_sniff_mode(hdev, ev->status);
1456 break;
1457
1458 case HCI_OP_EXIT_SNIFF_MODE:
1459 hci_cs_exit_sniff_mode(hdev, ev->status);
1460 break;
1461
1462 default:
1463 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1464 break;
1465 }
1466
1467 if (ev->ncmd) {
1468 atomic_set(&hdev->cmd_cnt, 1);
1469 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001470 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001471 }
1472}
1473
1474static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1475{
1476 struct hci_ev_role_change *ev = (void *) skb->data;
1477 struct hci_conn *conn;
1478
1479 BT_DBG("%s status %d", hdev->name, ev->status);
1480
1481 hci_dev_lock(hdev);
1482
1483 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1484 if (conn) {
1485 if (!ev->status) {
1486 if (ev->role)
1487 conn->link_mode &= ~HCI_LM_MASTER;
1488 else
1489 conn->link_mode |= HCI_LM_MASTER;
1490 }
1491
1492 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1493
1494 hci_role_switch_cfm(conn, ev->status, ev->role);
1495 }
1496
1497 hci_dev_unlock(hdev);
1498}
1499
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
1501{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001502 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001503 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 int i;
1505
1506 skb_pull(skb, sizeof(*ev));
1507
1508 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
1509
1510 if (skb->len < ev->num_hndl * 4) {
1511 BT_DBG("%s bad parameters", hdev->name);
1512 return;
1513 }
1514
1515 tasklet_disable(&hdev->tx_task);
1516
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001517 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 struct hci_conn *conn;
1519 __u16 handle, count;
1520
Harvey Harrison83985312008-05-02 16:25:46 -07001521 handle = get_unaligned_le16(ptr++);
1522 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523
1524 conn = hci_conn_hash_lookup_handle(hdev, handle);
1525 if (conn) {
1526 conn->sent -= count;
1527
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001528 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001529 hdev->acl_cnt += count;
1530 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531 hdev->acl_cnt = hdev->acl_pkts;
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001532 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001533 hdev->sco_cnt += count;
1534 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001535 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 }
1537 }
1538 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001539
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001540 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541
1542 tasklet_enable(&hdev->tx_task);
1543}
1544
Marcel Holtmann04837f62006-07-03 10:02:33 +02001545static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001547 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001548 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549
1550 BT_DBG("%s status %d", hdev->name, ev->status);
1551
1552 hci_dev_lock(hdev);
1553
Marcel Holtmann04837f62006-07-03 10:02:33 +02001554 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1555 if (conn) {
1556 conn->mode = ev->mode;
1557 conn->interval = __le16_to_cpu(ev->interval);
1558
1559 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
1560 if (conn->mode == HCI_CM_ACTIVE)
1561 conn->power_save = 1;
1562 else
1563 conn->power_save = 0;
1564 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001565
1566 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1567 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001568 }
1569
1570 hci_dev_unlock(hdev);
1571}
1572
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1574{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001575 struct hci_ev_pin_code_req *ev = (void *) skb->data;
1576 struct hci_conn *conn;
1577
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001578 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001579
1580 hci_dev_lock(hdev);
1581
1582 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Marcel Holtmann3d7a9d12009-05-09 12:09:21 -07001583 if (conn && conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001584 hci_conn_hold(conn);
1585 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1586 hci_conn_put(conn);
1587 }
1588
1589 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590}
1591
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1593{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001594 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595}
1596
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
1598{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001599 struct hci_ev_link_key_notify *ev = (void *) skb->data;
1600 struct hci_conn *conn;
1601
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001602 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001603
1604 hci_dev_lock(hdev);
1605
1606 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1607 if (conn) {
1608 hci_conn_hold(conn);
1609 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1610 hci_conn_put(conn);
1611 }
1612
1613 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614}
1615
Marcel Holtmann04837f62006-07-03 10:02:33 +02001616static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
1617{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001618 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001619 struct hci_conn *conn;
1620
1621 BT_DBG("%s status %d", hdev->name, ev->status);
1622
1623 hci_dev_lock(hdev);
1624
1625 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626 if (conn && !ev->status) {
1627 struct inquiry_entry *ie;
1628
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001629 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
1630 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631 ie->data.clock_offset = ev->clock_offset;
1632 ie->timestamp = jiffies;
1633 }
1634 }
1635
1636 hci_dev_unlock(hdev);
1637}
1638
Marcel Holtmanna8746412008-07-14 20:13:46 +02001639static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1640{
1641 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
1642 struct hci_conn *conn;
1643
1644 BT_DBG("%s status %d", hdev->name, ev->status);
1645
1646 hci_dev_lock(hdev);
1647
1648 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1649 if (conn && !ev->status)
1650 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
1651
1652 hci_dev_unlock(hdev);
1653}
1654
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001655static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
1656{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001657 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001658 struct inquiry_entry *ie;
1659
1660 BT_DBG("%s", hdev->name);
1661
1662 hci_dev_lock(hdev);
1663
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001664 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1665 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001666 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
1667 ie->timestamp = jiffies;
1668 }
1669
1670 hci_dev_unlock(hdev);
1671}
1672
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001673static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
1674{
1675 struct inquiry_data data;
1676 int num_rsp = *((__u8 *) skb->data);
1677
1678 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1679
1680 if (!num_rsp)
1681 return;
1682
1683 hci_dev_lock(hdev);
1684
1685 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
1686 struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);
1687
1688 for (; num_rsp; num_rsp--) {
1689 bacpy(&data.bdaddr, &info->bdaddr);
1690 data.pscan_rep_mode = info->pscan_rep_mode;
1691 data.pscan_period_mode = info->pscan_period_mode;
1692 data.pscan_mode = info->pscan_mode;
1693 memcpy(data.dev_class, info->dev_class, 3);
1694 data.clock_offset = info->clock_offset;
1695 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001696 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001697 info++;
1698 hci_inquiry_cache_update(hdev, &data);
1699 }
1700 } else {
1701 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
1702
1703 for (; num_rsp; num_rsp--) {
1704 bacpy(&data.bdaddr, &info->bdaddr);
1705 data.pscan_rep_mode = info->pscan_rep_mode;
1706 data.pscan_period_mode = info->pscan_period_mode;
1707 data.pscan_mode = 0x00;
1708 memcpy(data.dev_class, info->dev_class, 3);
1709 data.clock_offset = info->clock_offset;
1710 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001711 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001712 info++;
1713 hci_inquiry_cache_update(hdev, &data);
1714 }
1715 }
1716
1717 hci_dev_unlock(hdev);
1718}
1719
1720static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1721{
Marcel Holtmann41a96212008-07-14 20:13:48 +02001722 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
1723 struct hci_conn *conn;
1724
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001725 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02001726
Marcel Holtmann41a96212008-07-14 20:13:48 +02001727 hci_dev_lock(hdev);
1728
1729 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001730 if (!conn)
1731 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001732
Johan Hedbergccd556f2010-11-10 17:11:51 +02001733 if (!ev->status && ev->page == 0x01) {
1734 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001735
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001736 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
1737 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02001738 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02001739
Johan Hedbergccd556f2010-11-10 17:11:51 +02001740 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02001741 }
1742
Johan Hedbergccd556f2010-11-10 17:11:51 +02001743 if (conn->state != BT_CONFIG)
1744 goto unlock;
1745
Johan Hedberg127178d2010-11-18 22:22:29 +02001746 if (!ev->status) {
1747 struct hci_cp_remote_name_req cp;
1748 memset(&cp, 0, sizeof(cp));
1749 bacpy(&cp.bdaddr, &conn->dst);
1750 cp.pscan_rep_mode = 0x02;
1751 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1752 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001753
Johan Hedberg127178d2010-11-18 22:22:29 +02001754 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001755 conn->state = BT_CONNECTED;
1756 hci_proto_connect_cfm(conn, ev->status);
1757 hci_conn_put(conn);
1758 }
1759
1760unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02001761 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001762}
1763
1764static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1765{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001766 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
1767 struct hci_conn *conn;
1768
1769 BT_DBG("%s status %d", hdev->name, ev->status);
1770
1771 hci_dev_lock(hdev);
1772
1773 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02001774 if (!conn) {
1775 if (ev->link_type == ESCO_LINK)
1776 goto unlock;
1777
1778 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1779 if (!conn)
1780 goto unlock;
1781
1782 conn->type = SCO_LINK;
1783 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001784
Marcel Holtmann732547f2009-04-19 19:14:14 +02001785 switch (ev->status) {
1786 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001787 conn->handle = __le16_to_cpu(ev->handle);
1788 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001789
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001790 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001791 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02001792 break;
1793
Stephen Coe705e5712010-02-16 11:29:44 -05001794 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02001795 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08001796 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02001797 case 0x1f: /* Unspecified error */
1798 if (conn->out && conn->attempt < 2) {
1799 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
1800 (hdev->esco_type & EDR_ESCO_MASK);
1801 hci_setup_sync(conn, conn->link->handle);
1802 goto unlock;
1803 }
1804 /* fall through */
1805
1806 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001807 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02001808 break;
1809 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001810
1811 hci_proto_connect_cfm(conn, ev->status);
1812 if (ev->status)
1813 hci_conn_del(conn);
1814
1815unlock:
1816 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001817}
1818
1819static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
1820{
1821 BT_DBG("%s", hdev->name);
1822}
1823
Marcel Holtmann04837f62006-07-03 10:02:33 +02001824static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
1825{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001826 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001827 struct hci_conn *conn;
1828
1829 BT_DBG("%s status %d", hdev->name, ev->status);
1830
1831 hci_dev_lock(hdev);
1832
1833 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1834 if (conn) {
1835 }
1836
1837 hci_dev_unlock(hdev);
1838}
1839
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001840static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1841{
1842 struct inquiry_data data;
1843 struct extended_inquiry_info *info = (void *) (skb->data + 1);
1844 int num_rsp = *((__u8 *) skb->data);
1845
1846 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1847
1848 if (!num_rsp)
1849 return;
1850
1851 hci_dev_lock(hdev);
1852
1853 for (; num_rsp; num_rsp--) {
1854 bacpy(&data.bdaddr, &info->bdaddr);
1855 data.pscan_rep_mode = info->pscan_rep_mode;
1856 data.pscan_period_mode = info->pscan_period_mode;
1857 data.pscan_mode = 0x00;
1858 memcpy(data.dev_class, info->dev_class, 3);
1859 data.clock_offset = info->clock_offset;
1860 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001861 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001862 info++;
1863 hci_inquiry_cache_update(hdev, &data);
1864 }
1865
1866 hci_dev_unlock(hdev);
1867}
1868
Marcel Holtmann04936842008-07-14 20:13:48 +02001869static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1870{
1871 struct hci_ev_io_capa_request *ev = (void *) skb->data;
1872 struct hci_conn *conn;
1873
1874 BT_DBG("%s", hdev->name);
1875
1876 hci_dev_lock(hdev);
1877
1878 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1879 if (conn)
1880 hci_conn_hold(conn);
1881
1882 hci_dev_unlock(hdev);
1883}
1884
1885static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1886{
1887 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
1888 struct hci_conn *conn;
1889
1890 BT_DBG("%s", hdev->name);
1891
1892 hci_dev_lock(hdev);
1893
1894 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1895 if (conn)
1896 hci_conn_put(conn);
1897
1898 hci_dev_unlock(hdev);
1899}
1900
Marcel Holtmann41a96212008-07-14 20:13:48 +02001901static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1902{
1903 struct hci_ev_remote_host_features *ev = (void *) skb->data;
1904 struct inquiry_entry *ie;
1905
1906 BT_DBG("%s", hdev->name);
1907
1908 hci_dev_lock(hdev);
1909
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001910 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1911 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02001912 ie->data.ssp_mode = (ev->features[0] & 0x01);
1913
1914 hci_dev_unlock(hdev);
1915}
1916
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
1918{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001919 struct hci_event_hdr *hdr = (void *) skb->data;
1920 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921
1922 skb_pull(skb, HCI_EVENT_HDR_SIZE);
1923
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001924 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 case HCI_EV_INQUIRY_COMPLETE:
1926 hci_inquiry_complete_evt(hdev, skb);
1927 break;
1928
1929 case HCI_EV_INQUIRY_RESULT:
1930 hci_inquiry_result_evt(hdev, skb);
1931 break;
1932
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001933 case HCI_EV_CONN_COMPLETE:
1934 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02001935 break;
1936
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937 case HCI_EV_CONN_REQUEST:
1938 hci_conn_request_evt(hdev, skb);
1939 break;
1940
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 case HCI_EV_DISCONN_COMPLETE:
1942 hci_disconn_complete_evt(hdev, skb);
1943 break;
1944
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 case HCI_EV_AUTH_COMPLETE:
1946 hci_auth_complete_evt(hdev, skb);
1947 break;
1948
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001949 case HCI_EV_REMOTE_NAME:
1950 hci_remote_name_evt(hdev, skb);
1951 break;
1952
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953 case HCI_EV_ENCRYPT_CHANGE:
1954 hci_encrypt_change_evt(hdev, skb);
1955 break;
1956
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001957 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
1958 hci_change_link_key_complete_evt(hdev, skb);
1959 break;
1960
1961 case HCI_EV_REMOTE_FEATURES:
1962 hci_remote_features_evt(hdev, skb);
1963 break;
1964
1965 case HCI_EV_REMOTE_VERSION:
1966 hci_remote_version_evt(hdev, skb);
1967 break;
1968
1969 case HCI_EV_QOS_SETUP_COMPLETE:
1970 hci_qos_setup_complete_evt(hdev, skb);
1971 break;
1972
1973 case HCI_EV_CMD_COMPLETE:
1974 hci_cmd_complete_evt(hdev, skb);
1975 break;
1976
1977 case HCI_EV_CMD_STATUS:
1978 hci_cmd_status_evt(hdev, skb);
1979 break;
1980
1981 case HCI_EV_ROLE_CHANGE:
1982 hci_role_change_evt(hdev, skb);
1983 break;
1984
1985 case HCI_EV_NUM_COMP_PKTS:
1986 hci_num_comp_pkts_evt(hdev, skb);
1987 break;
1988
1989 case HCI_EV_MODE_CHANGE:
1990 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991 break;
1992
1993 case HCI_EV_PIN_CODE_REQ:
1994 hci_pin_code_request_evt(hdev, skb);
1995 break;
1996
1997 case HCI_EV_LINK_KEY_REQ:
1998 hci_link_key_request_evt(hdev, skb);
1999 break;
2000
2001 case HCI_EV_LINK_KEY_NOTIFY:
2002 hci_link_key_notify_evt(hdev, skb);
2003 break;
2004
2005 case HCI_EV_CLOCK_OFFSET:
2006 hci_clock_offset_evt(hdev, skb);
2007 break;
2008
Marcel Holtmanna8746412008-07-14 20:13:46 +02002009 case HCI_EV_PKT_TYPE_CHANGE:
2010 hci_pkt_type_change_evt(hdev, skb);
2011 break;
2012
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002013 case HCI_EV_PSCAN_REP_MODE:
2014 hci_pscan_rep_mode_evt(hdev, skb);
2015 break;
2016
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002017 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
2018 hci_inquiry_result_with_rssi_evt(hdev, skb);
2019 break;
2020
2021 case HCI_EV_REMOTE_EXT_FEATURES:
2022 hci_remote_ext_features_evt(hdev, skb);
2023 break;
2024
2025 case HCI_EV_SYNC_CONN_COMPLETE:
2026 hci_sync_conn_complete_evt(hdev, skb);
2027 break;
2028
2029 case HCI_EV_SYNC_CONN_CHANGED:
2030 hci_sync_conn_changed_evt(hdev, skb);
2031 break;
2032
Marcel Holtmann04837f62006-07-03 10:02:33 +02002033 case HCI_EV_SNIFF_SUBRATE:
2034 hci_sniff_subrate_evt(hdev, skb);
2035 break;
2036
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002037 case HCI_EV_EXTENDED_INQUIRY_RESULT:
2038 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002039 break;
2040
Marcel Holtmann04936842008-07-14 20:13:48 +02002041 case HCI_EV_IO_CAPA_REQUEST:
2042 hci_io_capa_request_evt(hdev, skb);
2043 break;
2044
2045 case HCI_EV_SIMPLE_PAIR_COMPLETE:
2046 hci_simple_pair_complete_evt(hdev, skb);
2047 break;
2048
Marcel Holtmann41a96212008-07-14 20:13:48 +02002049 case HCI_EV_REMOTE_HOST_FEATURES:
2050 hci_remote_host_features_evt(hdev, skb);
2051 break;
2052
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002053 default:
2054 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002055 break;
2056 }
2057
2058 kfree_skb(skb);
2059 hdev->stat.evt_rx++;
2060}
2061
2062/* Generate internal stack event */
2063void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
2064{
2065 struct hci_event_hdr *hdr;
2066 struct hci_ev_stack_internal *ev;
2067 struct sk_buff *skb;
2068
2069 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
2070 if (!skb)
2071 return;
2072
2073 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
2074 hdr->evt = HCI_EV_STACK_INTERNAL;
2075 hdr->plen = sizeof(*ev) + dlen;
2076
2077 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
2078 ev->type = type;
2079 memcpy(ev->data, data, dlen);
2080
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002081 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07002082 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002083
Marcel Holtmann0d48d932005-08-09 20:30:28 -07002084 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 skb->dev = (void *) hdev;
2086 hci_send_to_sock(hdev, skb);
2087 kfree_skb(skb);
2088}