blob: e0aaf30536670fe991ca6ee04804fe873ca21063 [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
196 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
197 if (!sent)
198 return;
199
Johan Hedbergb312b1612011-03-16 14:29:37 +0200200 if (test_bit(HCI_MGMT, &hdev->flags))
201 mgmt_set_local_name_complete(hdev->id, sent, status);
202
203 if (status)
204 return;
205
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200206 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200207}
208
209static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
210{
211 struct hci_rp_read_local_name *rp = (void *) skb->data;
212
213 BT_DBG("%s status 0x%x", hdev->name, rp->status);
214
215 if (rp->status)
216 return;
217
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200218 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200219}
220
221static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
222{
223 __u8 status = *((__u8 *) skb->data);
224 void *sent;
225
226 BT_DBG("%s status 0x%x", hdev->name, status);
227
228 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
229 if (!sent)
230 return;
231
232 if (!status) {
233 __u8 param = *((__u8 *) sent);
234
235 if (param == AUTH_ENABLED)
236 set_bit(HCI_AUTH, &hdev->flags);
237 else
238 clear_bit(HCI_AUTH, &hdev->flags);
239 }
240
Johan Hedberg23bb5762010-12-21 23:01:27 +0200241 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200242}
243
244static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
245{
246 __u8 status = *((__u8 *) skb->data);
247 void *sent;
248
249 BT_DBG("%s status 0x%x", hdev->name, status);
250
251 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
252 if (!sent)
253 return;
254
255 if (!status) {
256 __u8 param = *((__u8 *) sent);
257
258 if (param)
259 set_bit(HCI_ENCRYPT, &hdev->flags);
260 else
261 clear_bit(HCI_ENCRYPT, &hdev->flags);
262 }
263
Johan Hedberg23bb5762010-12-21 23:01:27 +0200264 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200265}
266
267static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
268{
269 __u8 status = *((__u8 *) skb->data);
270 void *sent;
271
272 BT_DBG("%s status 0x%x", hdev->name, status);
273
274 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
275 if (!sent)
276 return;
277
278 if (!status) {
279 __u8 param = *((__u8 *) sent);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200280 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200281
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200282 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
283 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200284
Johan Hedberg73f22f62010-12-29 16:00:25 +0200285 if (param & SCAN_INQUIRY) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200286 set_bit(HCI_ISCAN, &hdev->flags);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200287 if (!old_iscan)
288 mgmt_discoverable(hdev->id, 1);
289 } else if (old_iscan)
Johan Hedberg73f22f62010-12-29 16:00:25 +0200290 mgmt_discoverable(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200291
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200292 if (param & SCAN_PAGE) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200293 set_bit(HCI_PSCAN, &hdev->flags);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200294 if (!old_pscan)
295 mgmt_connectable(hdev->id, 1);
296 } else if (old_pscan)
297 mgmt_connectable(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200298 }
299
Johan Hedberg23bb5762010-12-21 23:01:27 +0200300 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200301}
302
303static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
304{
305 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
306
307 BT_DBG("%s status 0x%x", hdev->name, rp->status);
308
309 if (rp->status)
310 return;
311
312 memcpy(hdev->dev_class, rp->dev_class, 3);
313
314 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
315 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
316}
317
318static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
319{
320 __u8 status = *((__u8 *) skb->data);
321 void *sent;
322
323 BT_DBG("%s status 0x%x", hdev->name, status);
324
Marcel Holtmannf383f272008-07-14 20:13:47 +0200325 if (status)
326 return;
327
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200328 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
329 if (!sent)
330 return;
331
Marcel Holtmannf383f272008-07-14 20:13:47 +0200332 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200333}
334
335static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
336{
337 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200339
340 BT_DBG("%s status 0x%x", hdev->name, rp->status);
341
342 if (rp->status)
343 return;
344
345 setting = __le16_to_cpu(rp->voice_setting);
346
Marcel Holtmannf383f272008-07-14 20:13:47 +0200347 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200348 return;
349
350 hdev->voice_setting = setting;
351
352 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
353
354 if (hdev->notify) {
355 tasklet_disable(&hdev->tx_task);
356 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
357 tasklet_enable(&hdev->tx_task);
358 }
359}
360
361static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
362{
363 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200364 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 void *sent;
366
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200367 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368
Marcel Holtmannf383f272008-07-14 20:13:47 +0200369 if (status)
370 return;
371
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200372 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
373 if (!sent)
374 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
Marcel Holtmannf383f272008-07-14 20:13:47 +0200376 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377
Marcel Holtmannf383f272008-07-14 20:13:47 +0200378 if (hdev->voice_setting == setting)
379 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380
Marcel Holtmannf383f272008-07-14 20:13:47 +0200381 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
Marcel Holtmannf383f272008-07-14 20:13:47 +0200383 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
384
385 if (hdev->notify) {
386 tasklet_disable(&hdev->tx_task);
387 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
388 tasklet_enable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 }
390}
391
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200394 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200396 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397
Johan Hedberg23bb5762010-12-21 23:01:27 +0200398 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399}
400
Marcel Holtmann333140b2008-07-14 20:13:48 +0200401static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
402{
403 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
404
405 BT_DBG("%s status 0x%x", hdev->name, rp->status);
406
407 if (rp->status)
408 return;
409
410 hdev->ssp_mode = rp->mode;
411}
412
413static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
414{
415 __u8 status = *((__u8 *) skb->data);
416 void *sent;
417
418 BT_DBG("%s status 0x%x", hdev->name, status);
419
420 if (status)
421 return;
422
423 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
424 if (!sent)
425 return;
426
427 hdev->ssp_mode = *((__u8 *) sent);
428}
429
Johan Hedbergd5859e22011-01-25 01:19:58 +0200430static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
431{
432 if (hdev->features[6] & LMP_EXT_INQ)
433 return 2;
434
435 if (hdev->features[3] & LMP_RSSI_INQ)
436 return 1;
437
438 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
439 hdev->lmp_subver == 0x0757)
440 return 1;
441
442 if (hdev->manufacturer == 15) {
443 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
444 return 1;
445 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
446 return 1;
447 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
448 return 1;
449 }
450
451 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
452 hdev->lmp_subver == 0x1805)
453 return 1;
454
455 return 0;
456}
457
458static void hci_setup_inquiry_mode(struct hci_dev *hdev)
459{
460 u8 mode;
461
462 mode = hci_get_inquiry_mode(hdev);
463
464 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
465}
466
467static void hci_setup_event_mask(struct hci_dev *hdev)
468{
469 /* The second byte is 0xff instead of 0x9f (two reserved bits
470 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
471 * command otherwise */
472 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
473
474 /* Events for 1.2 and newer controllers */
475 if (hdev->lmp_ver > 1) {
476 events[4] |= 0x01; /* Flow Specification Complete */
477 events[4] |= 0x02; /* Inquiry Result with RSSI */
478 events[4] |= 0x04; /* Read Remote Extended Features Complete */
479 events[5] |= 0x08; /* Synchronous Connection Complete */
480 events[5] |= 0x10; /* Synchronous Connection Changed */
481 }
482
483 if (hdev->features[3] & LMP_RSSI_INQ)
484 events[4] |= 0x04; /* Inquiry Result with RSSI */
485
486 if (hdev->features[5] & LMP_SNIFF_SUBR)
487 events[5] |= 0x20; /* Sniff Subrating */
488
489 if (hdev->features[5] & LMP_PAUSE_ENC)
490 events[5] |= 0x80; /* Encryption Key Refresh Complete */
491
492 if (hdev->features[6] & LMP_EXT_INQ)
493 events[5] |= 0x40; /* Extended Inquiry Result */
494
495 if (hdev->features[6] & LMP_NO_FLUSH)
496 events[7] |= 0x01; /* Enhanced Flush Complete */
497
498 if (hdev->features[7] & LMP_LSTO)
499 events[6] |= 0x80; /* Link Supervision Timeout Changed */
500
501 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
502 events[6] |= 0x01; /* IO Capability Request */
503 events[6] |= 0x02; /* IO Capability Response */
504 events[6] |= 0x04; /* User Confirmation Request */
505 events[6] |= 0x08; /* User Passkey Request */
506 events[6] |= 0x10; /* Remote OOB Data Request */
507 events[6] |= 0x20; /* Simple Pairing Complete */
508 events[7] |= 0x04; /* User Passkey Notification */
509 events[7] |= 0x08; /* Keypress Notification */
510 events[7] |= 0x10; /* Remote Host Supported
511 * Features Notification */
512 }
513
514 if (hdev->features[4] & LMP_LE)
515 events[7] |= 0x20; /* LE Meta-Event */
516
517 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
518}
519
520static void hci_setup(struct hci_dev *hdev)
521{
522 hci_setup_event_mask(hdev);
523
524 if (hdev->lmp_ver > 1)
525 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
526
527 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
528 u8 mode = 0x01;
529 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
530 }
531
532 if (hdev->features[3] & LMP_RSSI_INQ)
533 hci_setup_inquiry_mode(hdev);
534
535 if (hdev->features[7] & LMP_INQ_TX_PWR)
536 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
537}
538
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200539static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
540{
541 struct hci_rp_read_local_version *rp = (void *) skb->data;
542
543 BT_DBG("%s status 0x%x", hdev->name, rp->status);
544
545 if (rp->status)
546 return;
547
548 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200549 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200550 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200551 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200552 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200553
554 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
555 hdev->manufacturer,
556 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200557
558 if (test_bit(HCI_INIT, &hdev->flags))
559 hci_setup(hdev);
560}
561
562static void hci_setup_link_policy(struct hci_dev *hdev)
563{
564 u16 link_policy = 0;
565
566 if (hdev->features[0] & LMP_RSWITCH)
567 link_policy |= HCI_LP_RSWITCH;
568 if (hdev->features[0] & LMP_HOLD)
569 link_policy |= HCI_LP_HOLD;
570 if (hdev->features[0] & LMP_SNIFF)
571 link_policy |= HCI_LP_SNIFF;
572 if (hdev->features[1] & LMP_PARK)
573 link_policy |= HCI_LP_PARK;
574
575 link_policy = cpu_to_le16(link_policy);
576 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
577 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200578}
579
580static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
581{
582 struct hci_rp_read_local_commands *rp = (void *) skb->data;
583
584 BT_DBG("%s status 0x%x", hdev->name, rp->status);
585
586 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200587 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200588
589 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200590
591 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
592 hci_setup_link_policy(hdev);
593
594done:
595 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200596}
597
598static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
599{
600 struct hci_rp_read_local_features *rp = (void *) skb->data;
601
602 BT_DBG("%s status 0x%x", hdev->name, rp->status);
603
604 if (rp->status)
605 return;
606
607 memcpy(hdev->features, rp->features, 8);
608
609 /* Adjust default settings according to features
610 * supported by device. */
611
612 if (hdev->features[0] & LMP_3SLOT)
613 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
614
615 if (hdev->features[0] & LMP_5SLOT)
616 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
617
618 if (hdev->features[1] & LMP_HV2) {
619 hdev->pkt_type |= (HCI_HV2);
620 hdev->esco_type |= (ESCO_HV2);
621 }
622
623 if (hdev->features[1] & LMP_HV3) {
624 hdev->pkt_type |= (HCI_HV3);
625 hdev->esco_type |= (ESCO_HV3);
626 }
627
628 if (hdev->features[3] & LMP_ESCO)
629 hdev->esco_type |= (ESCO_EV3);
630
631 if (hdev->features[4] & LMP_EV4)
632 hdev->esco_type |= (ESCO_EV4);
633
634 if (hdev->features[4] & LMP_EV5)
635 hdev->esco_type |= (ESCO_EV5);
636
Marcel Holtmannefc76882009-02-06 09:13:37 +0100637 if (hdev->features[5] & LMP_EDR_ESCO_2M)
638 hdev->esco_type |= (ESCO_2EV3);
639
640 if (hdev->features[5] & LMP_EDR_ESCO_3M)
641 hdev->esco_type |= (ESCO_3EV3);
642
643 if (hdev->features[5] & LMP_EDR_3S_ESCO)
644 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
645
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200646 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
647 hdev->features[0], hdev->features[1],
648 hdev->features[2], hdev->features[3],
649 hdev->features[4], hdev->features[5],
650 hdev->features[6], hdev->features[7]);
651}
652
653static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
654{
655 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
656
657 BT_DBG("%s status 0x%x", hdev->name, rp->status);
658
659 if (rp->status)
660 return;
661
662 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
663 hdev->sco_mtu = rp->sco_mtu;
664 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
665 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
666
667 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
668 hdev->sco_mtu = 64;
669 hdev->sco_pkts = 8;
670 }
671
672 hdev->acl_cnt = hdev->acl_pkts;
673 hdev->sco_cnt = hdev->sco_pkts;
674
675 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
676 hdev->acl_mtu, hdev->acl_pkts,
677 hdev->sco_mtu, hdev->sco_pkts);
678}
679
680static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
681{
682 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
683
684 BT_DBG("%s status 0x%x", hdev->name, rp->status);
685
686 if (!rp->status)
687 bacpy(&hdev->bdaddr, &rp->bdaddr);
688
Johan Hedberg23bb5762010-12-21 23:01:27 +0200689 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
690}
691
692static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
693{
694 __u8 status = *((__u8 *) skb->data);
695
696 BT_DBG("%s status 0x%x", hdev->name, status);
697
698 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200699}
700
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200701static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
702 struct sk_buff *skb)
703{
704 __u8 status = *((__u8 *) skb->data);
705
706 BT_DBG("%s status 0x%x", hdev->name, status);
707
708 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
709}
710
Johan Hedbergd5859e22011-01-25 01:19:58 +0200711static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
712{
713 __u8 status = *((__u8 *) skb->data);
714
715 BT_DBG("%s status 0x%x", hdev->name, status);
716
717 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
718}
719
720static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
721 struct sk_buff *skb)
722{
723 __u8 status = *((__u8 *) skb->data);
724
725 BT_DBG("%s status 0x%x", hdev->name, status);
726
727 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
728}
729
730static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
731 struct sk_buff *skb)
732{
733 __u8 status = *((__u8 *) skb->data);
734
735 BT_DBG("%s status 0x%x", hdev->name, status);
736
737 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
738}
739
740static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
741{
742 __u8 status = *((__u8 *) skb->data);
743
744 BT_DBG("%s status 0x%x", hdev->name, status);
745
746 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
747}
748
Johan Hedberg980e1a52011-01-22 06:10:07 +0200749static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
750{
751 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
752 struct hci_cp_pin_code_reply *cp;
753 struct hci_conn *conn;
754
755 BT_DBG("%s status 0x%x", hdev->name, rp->status);
756
757 if (test_bit(HCI_MGMT, &hdev->flags))
758 mgmt_pin_code_reply_complete(hdev->id, &rp->bdaddr, rp->status);
759
760 if (rp->status != 0)
761 return;
762
763 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
764 if (!cp)
765 return;
766
767 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
768 if (conn)
769 conn->pin_length = cp->pin_len;
770}
771
772static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
773{
774 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
775
776 BT_DBG("%s status 0x%x", hdev->name, rp->status);
777
778 if (test_bit(HCI_MGMT, &hdev->flags))
779 mgmt_pin_code_neg_reply_complete(hdev->id, &rp->bdaddr,
780 rp->status);
781}
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300782static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
783 struct sk_buff *skb)
784{
785 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
786
787 BT_DBG("%s status 0x%x", hdev->name, rp->status);
788
789 if (rp->status)
790 return;
791
792 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
793 hdev->le_pkts = rp->le_max_pkt;
794
795 hdev->le_cnt = hdev->le_pkts;
796
797 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
798
799 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
800}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200801
Johan Hedberga5c29682011-02-19 12:05:57 -0300802static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
803{
804 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
805
806 BT_DBG("%s status 0x%x", hdev->name, rp->status);
807
808 if (test_bit(HCI_MGMT, &hdev->flags))
809 mgmt_user_confirm_reply_complete(hdev->id, &rp->bdaddr,
810 rp->status);
811}
812
813static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
814 struct sk_buff *skb)
815{
816 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
817
818 BT_DBG("%s status 0x%x", hdev->name, rp->status);
819
820 if (test_bit(HCI_MGMT, &hdev->flags))
821 mgmt_user_confirm_neg_reply_complete(hdev->id, &rp->bdaddr,
822 rp->status);
823}
824
Szymon Jancc35938b2011-03-22 13:12:21 +0100825static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
826 struct sk_buff *skb)
827{
828 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
829
830 BT_DBG("%s status 0x%x", hdev->name, rp->status);
831
832 mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
833 rp->randomizer, rp->status);
834}
835
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200836static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
837{
838 BT_DBG("%s status 0x%x", hdev->name, status);
839
840 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +0200841 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200842
843 hci_conn_check_pending(hdev);
844 } else
845 set_bit(HCI_INQUIRY, &hdev->flags);
846}
847
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
849{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200850 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200853 BT_DBG("%s status 0x%x", hdev->name, status);
854
855 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 if (!cp)
857 return;
858
859 hci_dev_lock(hdev);
860
861 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
862
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200863 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864
865 if (status) {
866 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200867 if (status != 0x0c || conn->attempt > 2) {
868 conn->state = BT_CLOSED;
869 hci_proto_connect_cfm(conn, status);
870 hci_conn_del(conn);
871 } else
872 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 }
874 } else {
875 if (!conn) {
876 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
877 if (conn) {
878 conn->out = 1;
879 conn->link_mode |= HCI_LM_MASTER;
880 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -0300881 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 }
883 }
884
885 hci_dev_unlock(hdev);
886}
887
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200888static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200890 struct hci_cp_add_sco *cp;
891 struct hci_conn *acl, *sco;
892 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200894 BT_DBG("%s status 0x%x", hdev->name, status);
895
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200896 if (!status)
897 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200899 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
900 if (!cp)
901 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200903 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200905 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100906
907 hci_dev_lock(hdev);
908
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200909 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200910 if (acl) {
911 sco = acl->link;
912 if (sco) {
913 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200914
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200915 hci_proto_connect_cfm(sco, status);
916 hci_conn_del(sco);
917 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200918 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100919
920 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921}
922
Marcel Holtmannf8558552008-07-14 20:13:49 +0200923static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
924{
925 struct hci_cp_auth_requested *cp;
926 struct hci_conn *conn;
927
928 BT_DBG("%s status 0x%x", hdev->name, status);
929
930 if (!status)
931 return;
932
933 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
934 if (!cp)
935 return;
936
937 hci_dev_lock(hdev);
938
939 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
940 if (conn) {
941 if (conn->state == BT_CONFIG) {
942 hci_proto_connect_cfm(conn, status);
943 hci_conn_put(conn);
944 }
945 }
946
947 hci_dev_unlock(hdev);
948}
949
950static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
951{
952 struct hci_cp_set_conn_encrypt *cp;
953 struct hci_conn *conn;
954
955 BT_DBG("%s status 0x%x", hdev->name, status);
956
957 if (!status)
958 return;
959
960 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
961 if (!cp)
962 return;
963
964 hci_dev_lock(hdev);
965
966 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
967 if (conn) {
968 if (conn->state == BT_CONFIG) {
969 hci_proto_connect_cfm(conn, status);
970 hci_conn_put(conn);
971 }
972 }
973
974 hci_dev_unlock(hdev);
975}
976
Johan Hedberg127178d2010-11-18 22:22:29 +0200977static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +0100978 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +0200979{
Johan Hedberg392599b2010-11-18 22:22:28 +0200980 if (conn->state != BT_CONFIG || !conn->out)
981 return 0;
982
Johan Hedberg765c2a92011-01-19 12:06:52 +0530983 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +0200984 return 0;
985
986 /* Only request authentication for SSP connections or non-SSP
987 * devices with sec_level HIGH */
988 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Johan Hedberg765c2a92011-01-19 12:06:52 +0530989 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +0200990 return 0;
991
Johan Hedberg392599b2010-11-18 22:22:28 +0200992 return 1;
993}
994
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200995static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
996{
Johan Hedberg127178d2010-11-18 22:22:29 +0200997 struct hci_cp_remote_name_req *cp;
998 struct hci_conn *conn;
999
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001000 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001001
1002 /* If successful wait for the name req complete event before
1003 * checking for the need to do authentication */
1004 if (!status)
1005 return;
1006
1007 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1008 if (!cp)
1009 return;
1010
1011 hci_dev_lock(hdev);
1012
1013 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1014 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1015 struct hci_cp_auth_requested cp;
1016 cp.handle = __cpu_to_le16(conn->handle);
1017 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1018 }
1019
1020 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001021}
1022
Marcel Holtmann769be972008-07-14 20:13:49 +02001023static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1024{
1025 struct hci_cp_read_remote_features *cp;
1026 struct hci_conn *conn;
1027
1028 BT_DBG("%s status 0x%x", hdev->name, status);
1029
1030 if (!status)
1031 return;
1032
1033 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1034 if (!cp)
1035 return;
1036
1037 hci_dev_lock(hdev);
1038
1039 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1040 if (conn) {
1041 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001042 hci_proto_connect_cfm(conn, status);
1043 hci_conn_put(conn);
1044 }
1045 }
1046
1047 hci_dev_unlock(hdev);
1048}
1049
1050static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1051{
1052 struct hci_cp_read_remote_ext_features *cp;
1053 struct hci_conn *conn;
1054
1055 BT_DBG("%s status 0x%x", hdev->name, status);
1056
1057 if (!status)
1058 return;
1059
1060 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1061 if (!cp)
1062 return;
1063
1064 hci_dev_lock(hdev);
1065
1066 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1067 if (conn) {
1068 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001069 hci_proto_connect_cfm(conn, status);
1070 hci_conn_put(conn);
1071 }
1072 }
1073
1074 hci_dev_unlock(hdev);
1075}
1076
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001077static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1078{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001079 struct hci_cp_setup_sync_conn *cp;
1080 struct hci_conn *acl, *sco;
1081 __u16 handle;
1082
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001083 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001084
1085 if (!status)
1086 return;
1087
1088 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1089 if (!cp)
1090 return;
1091
1092 handle = __le16_to_cpu(cp->handle);
1093
1094 BT_DBG("%s handle %d", hdev->name, handle);
1095
1096 hci_dev_lock(hdev);
1097
1098 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001099 if (acl) {
1100 sco = acl->link;
1101 if (sco) {
1102 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001103
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001104 hci_proto_connect_cfm(sco, status);
1105 hci_conn_del(sco);
1106 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001107 }
1108
1109 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001110}
1111
1112static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1113{
1114 struct hci_cp_sniff_mode *cp;
1115 struct hci_conn *conn;
1116
1117 BT_DBG("%s status 0x%x", hdev->name, status);
1118
1119 if (!status)
1120 return;
1121
1122 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1123 if (!cp)
1124 return;
1125
1126 hci_dev_lock(hdev);
1127
1128 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001129 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001130 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1131
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001132 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1133 hci_sco_setup(conn, status);
1134 }
1135
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001136 hci_dev_unlock(hdev);
1137}
1138
1139static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1140{
1141 struct hci_cp_exit_sniff_mode *cp;
1142 struct hci_conn *conn;
1143
1144 BT_DBG("%s status 0x%x", hdev->name, status);
1145
1146 if (!status)
1147 return;
1148
1149 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1150 if (!cp)
1151 return;
1152
1153 hci_dev_lock(hdev);
1154
1155 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001156 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001157 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1158
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001159 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1160 hci_sco_setup(conn, status);
1161 }
1162
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001163 hci_dev_unlock(hdev);
1164}
1165
Ville Tervofcd89c02011-02-10 22:38:47 -03001166static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1167{
1168 struct hci_cp_le_create_conn *cp;
1169 struct hci_conn *conn;
1170
1171 BT_DBG("%s status 0x%x", hdev->name, status);
1172
1173 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1174 if (!cp)
1175 return;
1176
1177 hci_dev_lock(hdev);
1178
1179 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1180
1181 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1182 conn);
1183
1184 if (status) {
1185 if (conn && conn->state == BT_CONNECT) {
1186 conn->state = BT_CLOSED;
1187 hci_proto_connect_cfm(conn, status);
1188 hci_conn_del(conn);
1189 }
1190 } else {
1191 if (!conn) {
1192 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
1193 if (conn)
1194 conn->out = 1;
1195 else
1196 BT_ERR("No memory for new connection");
1197 }
1198 }
1199
1200 hci_dev_unlock(hdev);
1201}
1202
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001203static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1204{
1205 __u8 status = *((__u8 *) skb->data);
1206
1207 BT_DBG("%s status %d", hdev->name, status);
1208
1209 clear_bit(HCI_INQUIRY, &hdev->flags);
1210
Johan Hedberg23bb5762010-12-21 23:01:27 +02001211 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001212
1213 hci_conn_check_pending(hdev);
1214}
1215
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1217{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001218 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001219 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 int num_rsp = *((__u8 *) skb->data);
1221
1222 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1223
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001224 if (!num_rsp)
1225 return;
1226
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001228
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 for (; num_rsp; num_rsp--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230 bacpy(&data.bdaddr, &info->bdaddr);
1231 data.pscan_rep_mode = info->pscan_rep_mode;
1232 data.pscan_period_mode = info->pscan_period_mode;
1233 data.pscan_mode = info->pscan_mode;
1234 memcpy(data.dev_class, info->dev_class, 3);
1235 data.clock_offset = info->clock_offset;
1236 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001237 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 info++;
1239 hci_inquiry_cache_update(hdev, &data);
1240 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001241
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 hci_dev_unlock(hdev);
1243}
1244
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001245static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001247 struct hci_ev_conn_complete *ev = (void *) skb->data;
1248 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001250 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001251
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001253
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001254 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001255 if (!conn) {
1256 if (ev->link_type != SCO_LINK)
1257 goto unlock;
1258
1259 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1260 if (!conn)
1261 goto unlock;
1262
1263 conn->type = SCO_LINK;
1264 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001265
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001266 if (!ev->status) {
1267 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001268
1269 if (conn->type == ACL_LINK) {
1270 conn->state = BT_CONFIG;
1271 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001272 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedbergf7520542011-01-20 12:34:39 +02001273 mgmt_connected(hdev->id, &ev->bdaddr);
Marcel Holtmann769be972008-07-14 20:13:49 +02001274 } else
1275 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001276
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001277 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001278 hci_conn_add_sysfs(conn);
1279
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001280 if (test_bit(HCI_AUTH, &hdev->flags))
1281 conn->link_mode |= HCI_LM_AUTH;
1282
1283 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1284 conn->link_mode |= HCI_LM_ENCRYPT;
1285
1286 /* Get remote features */
1287 if (conn->type == ACL_LINK) {
1288 struct hci_cp_read_remote_features cp;
1289 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001290 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1291 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001292 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001293
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001294 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +02001295 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001296 struct hci_cp_change_conn_ptype cp;
1297 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001298 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1299 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1300 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001301 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001302 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001303 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001304 if (conn->type == ACL_LINK)
1305 mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status);
1306 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001307
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001308 if (conn->type == ACL_LINK)
1309 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001310
Marcel Holtmann769be972008-07-14 20:13:49 +02001311 if (ev->status) {
1312 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001313 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001314 } else if (ev->link_type != ACL_LINK)
1315 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001316
1317unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001319
1320 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321}
1322
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1324{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001325 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326 int mask = hdev->link_mode;
1327
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001328 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1329 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330
1331 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1332
Szymon Janc138d22e2011-02-17 16:44:23 +01001333 if ((mask & HCI_LM_ACCEPT) &&
1334 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001336 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338
1339 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001340
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001341 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1342 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001343 memcpy(ie->data.dev_class, ev->dev_class, 3);
1344
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1346 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001347 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1348 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001349 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 hci_dev_unlock(hdev);
1351 return;
1352 }
1353 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001354
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 memcpy(conn->dev_class, ev->dev_class, 3);
1356 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001357
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358 hci_dev_unlock(hdev);
1359
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001360 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1361 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001363 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001365 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1366 cp.role = 0x00; /* Become master */
1367 else
1368 cp.role = 0x01; /* Remain slave */
1369
1370 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1371 sizeof(cp), &cp);
1372 } else {
1373 struct hci_cp_accept_sync_conn_req cp;
1374
1375 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001376 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001377
1378 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1379 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1380 cp.max_latency = cpu_to_le16(0xffff);
1381 cp.content_format = cpu_to_le16(hdev->voice_setting);
1382 cp.retrans_effort = 0xff;
1383
1384 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1385 sizeof(cp), &cp);
1386 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 } else {
1388 /* Connection rejected */
1389 struct hci_cp_reject_conn_req cp;
1390
1391 bacpy(&cp.bdaddr, &ev->bdaddr);
1392 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001393 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394 }
1395}
1396
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1398{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001399 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001400 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401
1402 BT_DBG("%s status %d", hdev->name, ev->status);
1403
Johan Hedberg8962ee72011-01-20 12:40:27 +02001404 if (ev->status) {
1405 mgmt_disconnect_failed(hdev->id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 return;
Johan Hedberg8962ee72011-01-20 12:40:27 +02001407 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408
1409 hci_dev_lock(hdev);
1410
Marcel Holtmann04837f62006-07-03 10:02:33 +02001411 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001412 if (!conn)
1413 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001414
Johan Hedbergf7520542011-01-20 12:34:39 +02001415 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
Johan Hedbergf7520542011-01-20 12:34:39 +02001417 if (conn->type == ACL_LINK)
1418 mgmt_disconnected(hdev->id, &conn->dst);
1419
1420 hci_proto_disconn_cfm(conn, ev->reason);
1421 hci_conn_del(conn);
1422
1423unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 hci_dev_unlock(hdev);
1425}
1426
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001427static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1428{
1429 struct hci_ev_auth_complete *ev = (void *) skb->data;
1430 struct hci_conn *conn;
1431
1432 BT_DBG("%s status %d", hdev->name, ev->status);
1433
1434 hci_dev_lock(hdev);
1435
1436 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1437 if (conn) {
Johan Hedberg765c2a92011-01-19 12:06:52 +05301438 if (!ev->status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001439 conn->link_mode |= HCI_LM_AUTH;
Johan Hedberg765c2a92011-01-19 12:06:52 +05301440 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001441 } else {
1442 mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
Johan Hedbergda213f42010-06-18 11:08:56 +03001443 conn->sec_level = BT_SECURITY_LOW;
Johan Hedberg2a611692011-02-19 12:06:00 -03001444 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001445
1446 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1447
Marcel Holtmannf8558552008-07-14 20:13:49 +02001448 if (conn->state == BT_CONFIG) {
1449 if (!ev->status && hdev->ssp_mode > 0 &&
1450 conn->ssp_mode > 0) {
1451 struct hci_cp_set_conn_encrypt cp;
1452 cp.handle = ev->handle;
1453 cp.encrypt = 0x01;
1454 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1455 sizeof(cp), &cp);
1456 } else {
1457 conn->state = BT_CONNECTED;
1458 hci_proto_connect_cfm(conn, ev->status);
1459 hci_conn_put(conn);
1460 }
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001461 } else {
Marcel Holtmannf8558552008-07-14 20:13:49 +02001462 hci_auth_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001463
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001464 hci_conn_hold(conn);
1465 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1466 hci_conn_put(conn);
1467 }
1468
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001469 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1470 if (!ev->status) {
1471 struct hci_cp_set_conn_encrypt cp;
Marcel Holtmannf8558552008-07-14 20:13:49 +02001472 cp.handle = ev->handle;
1473 cp.encrypt = 0x01;
1474 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1475 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001476 } else {
1477 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1478 hci_encrypt_cfm(conn, ev->status, 0x00);
1479 }
1480 }
1481 }
1482
1483 hci_dev_unlock(hdev);
1484}
1485
1486static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1487{
Johan Hedberg127178d2010-11-18 22:22:29 +02001488 struct hci_ev_remote_name *ev = (void *) skb->data;
1489 struct hci_conn *conn;
1490
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001491 BT_DBG("%s", hdev->name);
1492
1493 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001494
1495 hci_dev_lock(hdev);
1496
1497 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1498 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1499 struct hci_cp_auth_requested cp;
1500 cp.handle = __cpu_to_le16(conn->handle);
1501 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1502 }
1503
1504 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001505}
1506
1507static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1508{
1509 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1510 struct hci_conn *conn;
1511
1512 BT_DBG("%s status %d", hdev->name, ev->status);
1513
1514 hci_dev_lock(hdev);
1515
1516 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1517 if (conn) {
1518 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001519 if (ev->encrypt) {
1520 /* Encryption implies authentication */
1521 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001522 conn->link_mode |= HCI_LM_ENCRYPT;
Marcel Holtmannae293192008-07-14 20:13:45 +02001523 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001524 conn->link_mode &= ~HCI_LM_ENCRYPT;
1525 }
1526
1527 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1528
Marcel Holtmannf8558552008-07-14 20:13:49 +02001529 if (conn->state == BT_CONFIG) {
1530 if (!ev->status)
1531 conn->state = BT_CONNECTED;
1532
1533 hci_proto_connect_cfm(conn, ev->status);
1534 hci_conn_put(conn);
1535 } else
1536 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001537 }
1538
1539 hci_dev_unlock(hdev);
1540}
1541
1542static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1543{
1544 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1545 struct hci_conn *conn;
1546
1547 BT_DBG("%s status %d", hdev->name, ev->status);
1548
1549 hci_dev_lock(hdev);
1550
1551 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1552 if (conn) {
1553 if (!ev->status)
1554 conn->link_mode |= HCI_LM_SECURE;
1555
1556 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1557
1558 hci_key_change_cfm(conn, ev->status);
1559 }
1560
1561 hci_dev_unlock(hdev);
1562}
1563
1564static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1565{
1566 struct hci_ev_remote_features *ev = (void *) skb->data;
1567 struct hci_conn *conn;
1568
1569 BT_DBG("%s status %d", hdev->name, ev->status);
1570
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001571 hci_dev_lock(hdev);
1572
1573 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001574 if (!conn)
1575 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001576
Johan Hedbergccd556f2010-11-10 17:11:51 +02001577 if (!ev->status)
1578 memcpy(conn->features, ev->features, 8);
1579
1580 if (conn->state != BT_CONFIG)
1581 goto unlock;
1582
1583 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1584 struct hci_cp_read_remote_ext_features cp;
1585 cp.handle = ev->handle;
1586 cp.page = 0x01;
1587 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001588 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001589 goto unlock;
1590 }
1591
Johan Hedberg127178d2010-11-18 22:22:29 +02001592 if (!ev->status) {
1593 struct hci_cp_remote_name_req cp;
1594 memset(&cp, 0, sizeof(cp));
1595 bacpy(&cp.bdaddr, &conn->dst);
1596 cp.pscan_rep_mode = 0x02;
1597 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1598 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001599
Johan Hedberg127178d2010-11-18 22:22:29 +02001600 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001601 conn->state = BT_CONNECTED;
1602 hci_proto_connect_cfm(conn, ev->status);
1603 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001604 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001605
Johan Hedbergccd556f2010-11-10 17:11:51 +02001606unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001607 hci_dev_unlock(hdev);
1608}
1609
1610static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1611{
1612 BT_DBG("%s", hdev->name);
1613}
1614
1615static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1616{
1617 BT_DBG("%s", hdev->name);
1618}
1619
1620static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1621{
1622 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1623 __u16 opcode;
1624
1625 skb_pull(skb, sizeof(*ev));
1626
1627 opcode = __le16_to_cpu(ev->opcode);
1628
1629 switch (opcode) {
1630 case HCI_OP_INQUIRY_CANCEL:
1631 hci_cc_inquiry_cancel(hdev, skb);
1632 break;
1633
1634 case HCI_OP_EXIT_PERIODIC_INQ:
1635 hci_cc_exit_periodic_inq(hdev, skb);
1636 break;
1637
1638 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1639 hci_cc_remote_name_req_cancel(hdev, skb);
1640 break;
1641
1642 case HCI_OP_ROLE_DISCOVERY:
1643 hci_cc_role_discovery(hdev, skb);
1644 break;
1645
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001646 case HCI_OP_READ_LINK_POLICY:
1647 hci_cc_read_link_policy(hdev, skb);
1648 break;
1649
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001650 case HCI_OP_WRITE_LINK_POLICY:
1651 hci_cc_write_link_policy(hdev, skb);
1652 break;
1653
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001654 case HCI_OP_READ_DEF_LINK_POLICY:
1655 hci_cc_read_def_link_policy(hdev, skb);
1656 break;
1657
1658 case HCI_OP_WRITE_DEF_LINK_POLICY:
1659 hci_cc_write_def_link_policy(hdev, skb);
1660 break;
1661
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001662 case HCI_OP_RESET:
1663 hci_cc_reset(hdev, skb);
1664 break;
1665
1666 case HCI_OP_WRITE_LOCAL_NAME:
1667 hci_cc_write_local_name(hdev, skb);
1668 break;
1669
1670 case HCI_OP_READ_LOCAL_NAME:
1671 hci_cc_read_local_name(hdev, skb);
1672 break;
1673
1674 case HCI_OP_WRITE_AUTH_ENABLE:
1675 hci_cc_write_auth_enable(hdev, skb);
1676 break;
1677
1678 case HCI_OP_WRITE_ENCRYPT_MODE:
1679 hci_cc_write_encrypt_mode(hdev, skb);
1680 break;
1681
1682 case HCI_OP_WRITE_SCAN_ENABLE:
1683 hci_cc_write_scan_enable(hdev, skb);
1684 break;
1685
1686 case HCI_OP_READ_CLASS_OF_DEV:
1687 hci_cc_read_class_of_dev(hdev, skb);
1688 break;
1689
1690 case HCI_OP_WRITE_CLASS_OF_DEV:
1691 hci_cc_write_class_of_dev(hdev, skb);
1692 break;
1693
1694 case HCI_OP_READ_VOICE_SETTING:
1695 hci_cc_read_voice_setting(hdev, skb);
1696 break;
1697
1698 case HCI_OP_WRITE_VOICE_SETTING:
1699 hci_cc_write_voice_setting(hdev, skb);
1700 break;
1701
1702 case HCI_OP_HOST_BUFFER_SIZE:
1703 hci_cc_host_buffer_size(hdev, skb);
1704 break;
1705
Marcel Holtmann333140b2008-07-14 20:13:48 +02001706 case HCI_OP_READ_SSP_MODE:
1707 hci_cc_read_ssp_mode(hdev, skb);
1708 break;
1709
1710 case HCI_OP_WRITE_SSP_MODE:
1711 hci_cc_write_ssp_mode(hdev, skb);
1712 break;
1713
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001714 case HCI_OP_READ_LOCAL_VERSION:
1715 hci_cc_read_local_version(hdev, skb);
1716 break;
1717
1718 case HCI_OP_READ_LOCAL_COMMANDS:
1719 hci_cc_read_local_commands(hdev, skb);
1720 break;
1721
1722 case HCI_OP_READ_LOCAL_FEATURES:
1723 hci_cc_read_local_features(hdev, skb);
1724 break;
1725
1726 case HCI_OP_READ_BUFFER_SIZE:
1727 hci_cc_read_buffer_size(hdev, skb);
1728 break;
1729
1730 case HCI_OP_READ_BD_ADDR:
1731 hci_cc_read_bd_addr(hdev, skb);
1732 break;
1733
Johan Hedberg23bb5762010-12-21 23:01:27 +02001734 case HCI_OP_WRITE_CA_TIMEOUT:
1735 hci_cc_write_ca_timeout(hdev, skb);
1736 break;
1737
Johan Hedbergb0916ea2011-01-10 13:44:55 +02001738 case HCI_OP_DELETE_STORED_LINK_KEY:
1739 hci_cc_delete_stored_link_key(hdev, skb);
1740 break;
1741
Johan Hedbergd5859e22011-01-25 01:19:58 +02001742 case HCI_OP_SET_EVENT_MASK:
1743 hci_cc_set_event_mask(hdev, skb);
1744 break;
1745
1746 case HCI_OP_WRITE_INQUIRY_MODE:
1747 hci_cc_write_inquiry_mode(hdev, skb);
1748 break;
1749
1750 case HCI_OP_READ_INQ_RSP_TX_POWER:
1751 hci_cc_read_inq_rsp_tx_power(hdev, skb);
1752 break;
1753
1754 case HCI_OP_SET_EVENT_FLT:
1755 hci_cc_set_event_flt(hdev, skb);
1756 break;
1757
Johan Hedberg980e1a52011-01-22 06:10:07 +02001758 case HCI_OP_PIN_CODE_REPLY:
1759 hci_cc_pin_code_reply(hdev, skb);
1760 break;
1761
1762 case HCI_OP_PIN_CODE_NEG_REPLY:
1763 hci_cc_pin_code_neg_reply(hdev, skb);
1764 break;
1765
Szymon Jancc35938b2011-03-22 13:12:21 +01001766 case HCI_OP_READ_LOCAL_OOB_DATA:
1767 hci_cc_read_local_oob_data_reply(hdev, skb);
1768 break;
1769
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001770 case HCI_OP_LE_READ_BUFFER_SIZE:
1771 hci_cc_le_read_buffer_size(hdev, skb);
1772 break;
1773
Johan Hedberga5c29682011-02-19 12:05:57 -03001774 case HCI_OP_USER_CONFIRM_REPLY:
1775 hci_cc_user_confirm_reply(hdev, skb);
1776 break;
1777
1778 case HCI_OP_USER_CONFIRM_NEG_REPLY:
1779 hci_cc_user_confirm_neg_reply(hdev, skb);
1780 break;
1781
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001782 default:
1783 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1784 break;
1785 }
1786
Ville Tervo6bd32322011-02-16 16:32:41 +02001787 if (ev->opcode != HCI_OP_NOP)
1788 del_timer(&hdev->cmd_timer);
1789
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001790 if (ev->ncmd) {
1791 atomic_set(&hdev->cmd_cnt, 1);
1792 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001793 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001794 }
1795}
1796
1797static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1798{
1799 struct hci_ev_cmd_status *ev = (void *) skb->data;
1800 __u16 opcode;
1801
1802 skb_pull(skb, sizeof(*ev));
1803
1804 opcode = __le16_to_cpu(ev->opcode);
1805
1806 switch (opcode) {
1807 case HCI_OP_INQUIRY:
1808 hci_cs_inquiry(hdev, ev->status);
1809 break;
1810
1811 case HCI_OP_CREATE_CONN:
1812 hci_cs_create_conn(hdev, ev->status);
1813 break;
1814
1815 case HCI_OP_ADD_SCO:
1816 hci_cs_add_sco(hdev, ev->status);
1817 break;
1818
Marcel Holtmannf8558552008-07-14 20:13:49 +02001819 case HCI_OP_AUTH_REQUESTED:
1820 hci_cs_auth_requested(hdev, ev->status);
1821 break;
1822
1823 case HCI_OP_SET_CONN_ENCRYPT:
1824 hci_cs_set_conn_encrypt(hdev, ev->status);
1825 break;
1826
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001827 case HCI_OP_REMOTE_NAME_REQ:
1828 hci_cs_remote_name_req(hdev, ev->status);
1829 break;
1830
Marcel Holtmann769be972008-07-14 20:13:49 +02001831 case HCI_OP_READ_REMOTE_FEATURES:
1832 hci_cs_read_remote_features(hdev, ev->status);
1833 break;
1834
1835 case HCI_OP_READ_REMOTE_EXT_FEATURES:
1836 hci_cs_read_remote_ext_features(hdev, ev->status);
1837 break;
1838
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001839 case HCI_OP_SETUP_SYNC_CONN:
1840 hci_cs_setup_sync_conn(hdev, ev->status);
1841 break;
1842
1843 case HCI_OP_SNIFF_MODE:
1844 hci_cs_sniff_mode(hdev, ev->status);
1845 break;
1846
1847 case HCI_OP_EXIT_SNIFF_MODE:
1848 hci_cs_exit_sniff_mode(hdev, ev->status);
1849 break;
1850
Johan Hedberg8962ee72011-01-20 12:40:27 +02001851 case HCI_OP_DISCONNECT:
1852 if (ev->status != 0)
1853 mgmt_disconnect_failed(hdev->id);
1854 break;
1855
Ville Tervofcd89c02011-02-10 22:38:47 -03001856 case HCI_OP_LE_CREATE_CONN:
1857 hci_cs_le_create_conn(hdev, ev->status);
1858 break;
1859
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001860 default:
1861 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1862 break;
1863 }
1864
Ville Tervo6bd32322011-02-16 16:32:41 +02001865 if (ev->opcode != HCI_OP_NOP)
1866 del_timer(&hdev->cmd_timer);
1867
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001868 if (ev->ncmd) {
1869 atomic_set(&hdev->cmd_cnt, 1);
1870 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001871 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001872 }
1873}
1874
1875static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1876{
1877 struct hci_ev_role_change *ev = (void *) skb->data;
1878 struct hci_conn *conn;
1879
1880 BT_DBG("%s status %d", hdev->name, ev->status);
1881
1882 hci_dev_lock(hdev);
1883
1884 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1885 if (conn) {
1886 if (!ev->status) {
1887 if (ev->role)
1888 conn->link_mode &= ~HCI_LM_MASTER;
1889 else
1890 conn->link_mode |= HCI_LM_MASTER;
1891 }
1892
1893 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1894
1895 hci_role_switch_cfm(conn, ev->status, ev->role);
1896 }
1897
1898 hci_dev_unlock(hdev);
1899}
1900
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
1902{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001903 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001904 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905 int i;
1906
1907 skb_pull(skb, sizeof(*ev));
1908
1909 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
1910
1911 if (skb->len < ev->num_hndl * 4) {
1912 BT_DBG("%s bad parameters", hdev->name);
1913 return;
1914 }
1915
1916 tasklet_disable(&hdev->tx_task);
1917
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001918 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 struct hci_conn *conn;
1920 __u16 handle, count;
1921
Harvey Harrison83985312008-05-02 16:25:46 -07001922 handle = get_unaligned_le16(ptr++);
1923 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924
1925 conn = hci_conn_hash_lookup_handle(hdev, handle);
1926 if (conn) {
1927 conn->sent -= count;
1928
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001929 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001930 hdev->acl_cnt += count;
1931 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932 hdev->acl_cnt = hdev->acl_pkts;
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001933 } else if (conn->type == LE_LINK) {
1934 if (hdev->le_pkts) {
1935 hdev->le_cnt += count;
1936 if (hdev->le_cnt > hdev->le_pkts)
1937 hdev->le_cnt = hdev->le_pkts;
1938 } else {
1939 hdev->acl_cnt += count;
1940 if (hdev->acl_cnt > hdev->acl_pkts)
1941 hdev->acl_cnt = hdev->acl_pkts;
1942 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001943 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001944 hdev->sco_cnt += count;
1945 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001946 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947 }
1948 }
1949 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001950
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001951 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952
1953 tasklet_enable(&hdev->tx_task);
1954}
1955
Marcel Holtmann04837f62006-07-03 10:02:33 +02001956static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001958 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001959 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960
1961 BT_DBG("%s status %d", hdev->name, ev->status);
1962
1963 hci_dev_lock(hdev);
1964
Marcel Holtmann04837f62006-07-03 10:02:33 +02001965 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1966 if (conn) {
1967 conn->mode = ev->mode;
1968 conn->interval = __le16_to_cpu(ev->interval);
1969
1970 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
1971 if (conn->mode == HCI_CM_ACTIVE)
1972 conn->power_save = 1;
1973 else
1974 conn->power_save = 0;
1975 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001976
1977 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1978 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001979 }
1980
1981 hci_dev_unlock(hdev);
1982}
1983
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1985{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001986 struct hci_ev_pin_code_req *ev = (void *) skb->data;
1987 struct hci_conn *conn;
1988
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001989 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001990
1991 hci_dev_lock(hdev);
1992
1993 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Marcel Holtmann3d7a9d12009-05-09 12:09:21 -07001994 if (conn && conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001995 hci_conn_hold(conn);
1996 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1997 hci_conn_put(conn);
1998 }
1999
Johan Hedberg03b555e2011-01-04 15:40:05 +02002000 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
2001 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2002 sizeof(ev->bdaddr), &ev->bdaddr);
2003
Johan Hedberg980e1a52011-01-22 06:10:07 +02002004 if (test_bit(HCI_MGMT, &hdev->flags))
2005 mgmt_pin_code_request(hdev->id, &ev->bdaddr);
2006
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002007 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008}
2009
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2011{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002012 struct hci_ev_link_key_req *ev = (void *) skb->data;
2013 struct hci_cp_link_key_reply cp;
2014 struct hci_conn *conn;
2015 struct link_key *key;
2016
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002017 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002018
2019 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
2020 return;
2021
2022 hci_dev_lock(hdev);
2023
2024 key = hci_find_link_key(hdev, &ev->bdaddr);
2025 if (!key) {
2026 BT_DBG("%s link key not found for %s", hdev->name,
2027 batostr(&ev->bdaddr));
2028 goto not_found;
2029 }
2030
2031 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2032 batostr(&ev->bdaddr));
2033
2034 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) {
2035 BT_DBG("%s ignoring debug key", hdev->name);
2036 goto not_found;
2037 }
2038
2039 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2040
2041 if (key->type == 0x04 && conn && conn->auth_type != 0xff &&
2042 (conn->auth_type & 0x01)) {
2043 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2044 goto not_found;
2045 }
2046
2047 bacpy(&cp.bdaddr, &ev->bdaddr);
2048 memcpy(cp.link_key, key->val, 16);
2049
2050 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2051
2052 hci_dev_unlock(hdev);
2053
2054 return;
2055
2056not_found:
2057 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2058 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002059}
2060
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2062{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002063 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2064 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002065 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002066
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002067 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002068
2069 hci_dev_lock(hdev);
2070
2071 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2072 if (conn) {
2073 hci_conn_hold(conn);
2074 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002075 pin_len = conn->pin_length;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002076 hci_conn_put(conn);
2077 }
2078
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002079 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
2080 hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key,
2081 ev->key_type, pin_len);
2082
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002083 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084}
2085
Marcel Holtmann04837f62006-07-03 10:02:33 +02002086static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2087{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002088 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002089 struct hci_conn *conn;
2090
2091 BT_DBG("%s status %d", hdev->name, ev->status);
2092
2093 hci_dev_lock(hdev);
2094
2095 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002096 if (conn && !ev->status) {
2097 struct inquiry_entry *ie;
2098
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002099 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2100 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002101 ie->data.clock_offset = ev->clock_offset;
2102 ie->timestamp = jiffies;
2103 }
2104 }
2105
2106 hci_dev_unlock(hdev);
2107}
2108
Marcel Holtmanna8746412008-07-14 20:13:46 +02002109static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2110{
2111 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2112 struct hci_conn *conn;
2113
2114 BT_DBG("%s status %d", hdev->name, ev->status);
2115
2116 hci_dev_lock(hdev);
2117
2118 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2119 if (conn && !ev->status)
2120 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2121
2122 hci_dev_unlock(hdev);
2123}
2124
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002125static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2126{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002127 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002128 struct inquiry_entry *ie;
2129
2130 BT_DBG("%s", hdev->name);
2131
2132 hci_dev_lock(hdev);
2133
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002134 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2135 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002136 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2137 ie->timestamp = jiffies;
2138 }
2139
2140 hci_dev_unlock(hdev);
2141}
2142
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002143static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2144{
2145 struct inquiry_data data;
2146 int num_rsp = *((__u8 *) skb->data);
2147
2148 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2149
2150 if (!num_rsp)
2151 return;
2152
2153 hci_dev_lock(hdev);
2154
2155 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002156 struct inquiry_info_with_rssi_and_pscan_mode *info;
2157 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002158
2159 for (; num_rsp; num_rsp--) {
2160 bacpy(&data.bdaddr, &info->bdaddr);
2161 data.pscan_rep_mode = info->pscan_rep_mode;
2162 data.pscan_period_mode = info->pscan_period_mode;
2163 data.pscan_mode = info->pscan_mode;
2164 memcpy(data.dev_class, info->dev_class, 3);
2165 data.clock_offset = info->clock_offset;
2166 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002167 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002168 info++;
2169 hci_inquiry_cache_update(hdev, &data);
2170 }
2171 } else {
2172 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2173
2174 for (; num_rsp; num_rsp--) {
2175 bacpy(&data.bdaddr, &info->bdaddr);
2176 data.pscan_rep_mode = info->pscan_rep_mode;
2177 data.pscan_period_mode = info->pscan_period_mode;
2178 data.pscan_mode = 0x00;
2179 memcpy(data.dev_class, info->dev_class, 3);
2180 data.clock_offset = info->clock_offset;
2181 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002182 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002183 info++;
2184 hci_inquiry_cache_update(hdev, &data);
2185 }
2186 }
2187
2188 hci_dev_unlock(hdev);
2189}
2190
2191static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2192{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002193 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2194 struct hci_conn *conn;
2195
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002196 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002197
Marcel Holtmann41a96212008-07-14 20:13:48 +02002198 hci_dev_lock(hdev);
2199
2200 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002201 if (!conn)
2202 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002203
Johan Hedbergccd556f2010-11-10 17:11:51 +02002204 if (!ev->status && ev->page == 0x01) {
2205 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002206
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002207 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2208 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002209 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002210
Johan Hedbergccd556f2010-11-10 17:11:51 +02002211 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002212 }
2213
Johan Hedbergccd556f2010-11-10 17:11:51 +02002214 if (conn->state != BT_CONFIG)
2215 goto unlock;
2216
Johan Hedberg127178d2010-11-18 22:22:29 +02002217 if (!ev->status) {
2218 struct hci_cp_remote_name_req cp;
2219 memset(&cp, 0, sizeof(cp));
2220 bacpy(&cp.bdaddr, &conn->dst);
2221 cp.pscan_rep_mode = 0x02;
2222 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2223 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002224
Johan Hedberg127178d2010-11-18 22:22:29 +02002225 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002226 conn->state = BT_CONNECTED;
2227 hci_proto_connect_cfm(conn, ev->status);
2228 hci_conn_put(conn);
2229 }
2230
2231unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002232 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002233}
2234
2235static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2236{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002237 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2238 struct hci_conn *conn;
2239
2240 BT_DBG("%s status %d", hdev->name, ev->status);
2241
2242 hci_dev_lock(hdev);
2243
2244 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002245 if (!conn) {
2246 if (ev->link_type == ESCO_LINK)
2247 goto unlock;
2248
2249 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2250 if (!conn)
2251 goto unlock;
2252
2253 conn->type = SCO_LINK;
2254 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002255
Marcel Holtmann732547f2009-04-19 19:14:14 +02002256 switch (ev->status) {
2257 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002258 conn->handle = __le16_to_cpu(ev->handle);
2259 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002260
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002261 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002262 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002263 break;
2264
Stephen Coe705e5712010-02-16 11:29:44 -05002265 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002266 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002267 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002268 case 0x1f: /* Unspecified error */
2269 if (conn->out && conn->attempt < 2) {
2270 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2271 (hdev->esco_type & EDR_ESCO_MASK);
2272 hci_setup_sync(conn, conn->link->handle);
2273 goto unlock;
2274 }
2275 /* fall through */
2276
2277 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002278 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002279 break;
2280 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002281
2282 hci_proto_connect_cfm(conn, ev->status);
2283 if (ev->status)
2284 hci_conn_del(conn);
2285
2286unlock:
2287 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002288}
2289
2290static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2291{
2292 BT_DBG("%s", hdev->name);
2293}
2294
Marcel Holtmann04837f62006-07-03 10:02:33 +02002295static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2296{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002297 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002298
2299 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002300}
2301
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002302static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2303{
2304 struct inquiry_data data;
2305 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2306 int num_rsp = *((__u8 *) skb->data);
2307
2308 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2309
2310 if (!num_rsp)
2311 return;
2312
2313 hci_dev_lock(hdev);
2314
2315 for (; num_rsp; num_rsp--) {
2316 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002317 data.pscan_rep_mode = info->pscan_rep_mode;
2318 data.pscan_period_mode = info->pscan_period_mode;
2319 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002320 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002321 data.clock_offset = info->clock_offset;
2322 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002323 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002324 info++;
2325 hci_inquiry_cache_update(hdev, &data);
2326 }
2327
2328 hci_dev_unlock(hdev);
2329}
2330
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002331static inline u8 hci_get_auth_req(struct hci_conn *conn)
2332{
2333 /* If remote requests dedicated bonding follow that lead */
2334 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2335 /* If both remote and local IO capabilities allow MITM
2336 * protection then require it, otherwise don't */
2337 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2338 return 0x02;
2339 else
2340 return 0x03;
2341 }
2342
2343 /* If remote requests no-bonding follow that lead */
2344 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
2345 return 0x00;
2346
2347 return conn->auth_type;
2348}
2349
Marcel Holtmann04936842008-07-14 20:13:48 +02002350static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2351{
2352 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2353 struct hci_conn *conn;
2354
2355 BT_DBG("%s", hdev->name);
2356
2357 hci_dev_lock(hdev);
2358
2359 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002360 if (!conn)
2361 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002362
Johan Hedberg03b555e2011-01-04 15:40:05 +02002363 hci_conn_hold(conn);
2364
2365 if (!test_bit(HCI_MGMT, &hdev->flags))
2366 goto unlock;
2367
2368 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
2369 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002370 struct hci_cp_io_capability_reply cp;
2371
2372 bacpy(&cp.bdaddr, &ev->bdaddr);
2373 cp.capability = conn->io_capability;
2374 cp.oob_data = 0;
2375 cp.authentication = hci_get_auth_req(conn);
2376
2377 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2378 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002379 } else {
2380 struct hci_cp_io_capability_neg_reply cp;
2381
2382 bacpy(&cp.bdaddr, &ev->bdaddr);
2383 cp.reason = 0x16; /* Pairing not allowed */
2384
2385 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2386 sizeof(cp), &cp);
2387 }
2388
2389unlock:
2390 hci_dev_unlock(hdev);
2391}
2392
2393static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2394{
2395 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2396 struct hci_conn *conn;
2397
2398 BT_DBG("%s", hdev->name);
2399
2400 hci_dev_lock(hdev);
2401
2402 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2403 if (!conn)
2404 goto unlock;
2405
2406 hci_conn_hold(conn);
2407
2408 conn->remote_cap = ev->capability;
2409 conn->remote_oob = ev->oob_data;
2410 conn->remote_auth = ev->authentication;
2411
2412unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002413 hci_dev_unlock(hdev);
2414}
2415
Johan Hedberga5c29682011-02-19 12:05:57 -03002416static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2417 struct sk_buff *skb)
2418{
2419 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
2420
2421 BT_DBG("%s", hdev->name);
2422
2423 hci_dev_lock(hdev);
2424
2425 if (test_bit(HCI_MGMT, &hdev->flags))
2426 mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
2427
2428 hci_dev_unlock(hdev);
2429}
2430
Marcel Holtmann04936842008-07-14 20:13:48 +02002431static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2432{
2433 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
2434 struct hci_conn *conn;
2435
2436 BT_DBG("%s", hdev->name);
2437
2438 hci_dev_lock(hdev);
2439
2440 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03002441 if (!conn)
2442 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002443
Johan Hedberg2a611692011-02-19 12:06:00 -03002444 /* To avoid duplicate auth_failed events to user space we check
2445 * the HCI_CONN_AUTH_PEND flag which will be set if we
2446 * initiated the authentication. A traditional auth_complete
2447 * event gets always produced as initiator and is also mapped to
2448 * the mgmt_auth_failed event */
2449 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
2450 mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
2451
2452 hci_conn_put(conn);
2453
2454unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002455 hci_dev_unlock(hdev);
2456}
2457
Marcel Holtmann41a96212008-07-14 20:13:48 +02002458static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2459{
2460 struct hci_ev_remote_host_features *ev = (void *) skb->data;
2461 struct inquiry_entry *ie;
2462
2463 BT_DBG("%s", hdev->name);
2464
2465 hci_dev_lock(hdev);
2466
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002467 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2468 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02002469 ie->data.ssp_mode = (ev->features[0] & 0x01);
2470
2471 hci_dev_unlock(hdev);
2472}
2473
Szymon Janc2763eda2011-03-22 13:12:22 +01002474static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
2475 struct sk_buff *skb)
2476{
2477 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
2478 struct oob_data *data;
2479
2480 BT_DBG("%s", hdev->name);
2481
2482 hci_dev_lock(hdev);
2483
2484 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
2485 if (data) {
2486 struct hci_cp_remote_oob_data_reply cp;
2487
2488 bacpy(&cp.bdaddr, &ev->bdaddr);
2489 memcpy(cp.hash, data->hash, sizeof(cp.hash));
2490 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
2491
2492 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
2493 &cp);
2494 } else {
2495 struct hci_cp_remote_oob_data_neg_reply cp;
2496
2497 bacpy(&cp.bdaddr, &ev->bdaddr);
2498 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
2499 &cp);
2500 }
2501
2502 hci_dev_unlock(hdev);
2503}
2504
Ville Tervofcd89c02011-02-10 22:38:47 -03002505static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2506{
2507 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2508 struct hci_conn *conn;
2509
2510 BT_DBG("%s status %d", hdev->name, ev->status);
2511
2512 hci_dev_lock(hdev);
2513
2514 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03002515 if (!conn) {
2516 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
2517 if (!conn) {
2518 BT_ERR("No memory for new connection");
2519 hci_dev_unlock(hdev);
2520 return;
2521 }
2522 }
Ville Tervofcd89c02011-02-10 22:38:47 -03002523
2524 if (ev->status) {
2525 hci_proto_connect_cfm(conn, ev->status);
2526 conn->state = BT_CLOSED;
2527 hci_conn_del(conn);
2528 goto unlock;
2529 }
2530
2531 conn->handle = __le16_to_cpu(ev->handle);
2532 conn->state = BT_CONNECTED;
2533
2534 hci_conn_hold_device(conn);
2535 hci_conn_add_sysfs(conn);
2536
2537 hci_proto_connect_cfm(conn, ev->status);
2538
2539unlock:
2540 hci_dev_unlock(hdev);
2541}
2542
2543static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
2544{
2545 struct hci_ev_le_meta *le_ev = (void *) skb->data;
2546
2547 skb_pull(skb, sizeof(*le_ev));
2548
2549 switch (le_ev->subevent) {
2550 case HCI_EV_LE_CONN_COMPLETE:
2551 hci_le_conn_complete_evt(hdev, skb);
2552 break;
2553
2554 default:
2555 break;
2556 }
2557}
2558
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
2560{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002561 struct hci_event_hdr *hdr = (void *) skb->data;
2562 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563
2564 skb_pull(skb, HCI_EVENT_HDR_SIZE);
2565
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002566 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567 case HCI_EV_INQUIRY_COMPLETE:
2568 hci_inquiry_complete_evt(hdev, skb);
2569 break;
2570
2571 case HCI_EV_INQUIRY_RESULT:
2572 hci_inquiry_result_evt(hdev, skb);
2573 break;
2574
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002575 case HCI_EV_CONN_COMPLETE:
2576 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02002577 break;
2578
Linus Torvalds1da177e2005-04-16 15:20:36 -07002579 case HCI_EV_CONN_REQUEST:
2580 hci_conn_request_evt(hdev, skb);
2581 break;
2582
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583 case HCI_EV_DISCONN_COMPLETE:
2584 hci_disconn_complete_evt(hdev, skb);
2585 break;
2586
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587 case HCI_EV_AUTH_COMPLETE:
2588 hci_auth_complete_evt(hdev, skb);
2589 break;
2590
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002591 case HCI_EV_REMOTE_NAME:
2592 hci_remote_name_evt(hdev, skb);
2593 break;
2594
Linus Torvalds1da177e2005-04-16 15:20:36 -07002595 case HCI_EV_ENCRYPT_CHANGE:
2596 hci_encrypt_change_evt(hdev, skb);
2597 break;
2598
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002599 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
2600 hci_change_link_key_complete_evt(hdev, skb);
2601 break;
2602
2603 case HCI_EV_REMOTE_FEATURES:
2604 hci_remote_features_evt(hdev, skb);
2605 break;
2606
2607 case HCI_EV_REMOTE_VERSION:
2608 hci_remote_version_evt(hdev, skb);
2609 break;
2610
2611 case HCI_EV_QOS_SETUP_COMPLETE:
2612 hci_qos_setup_complete_evt(hdev, skb);
2613 break;
2614
2615 case HCI_EV_CMD_COMPLETE:
2616 hci_cmd_complete_evt(hdev, skb);
2617 break;
2618
2619 case HCI_EV_CMD_STATUS:
2620 hci_cmd_status_evt(hdev, skb);
2621 break;
2622
2623 case HCI_EV_ROLE_CHANGE:
2624 hci_role_change_evt(hdev, skb);
2625 break;
2626
2627 case HCI_EV_NUM_COMP_PKTS:
2628 hci_num_comp_pkts_evt(hdev, skb);
2629 break;
2630
2631 case HCI_EV_MODE_CHANGE:
2632 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633 break;
2634
2635 case HCI_EV_PIN_CODE_REQ:
2636 hci_pin_code_request_evt(hdev, skb);
2637 break;
2638
2639 case HCI_EV_LINK_KEY_REQ:
2640 hci_link_key_request_evt(hdev, skb);
2641 break;
2642
2643 case HCI_EV_LINK_KEY_NOTIFY:
2644 hci_link_key_notify_evt(hdev, skb);
2645 break;
2646
2647 case HCI_EV_CLOCK_OFFSET:
2648 hci_clock_offset_evt(hdev, skb);
2649 break;
2650
Marcel Holtmanna8746412008-07-14 20:13:46 +02002651 case HCI_EV_PKT_TYPE_CHANGE:
2652 hci_pkt_type_change_evt(hdev, skb);
2653 break;
2654
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002655 case HCI_EV_PSCAN_REP_MODE:
2656 hci_pscan_rep_mode_evt(hdev, skb);
2657 break;
2658
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002659 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
2660 hci_inquiry_result_with_rssi_evt(hdev, skb);
2661 break;
2662
2663 case HCI_EV_REMOTE_EXT_FEATURES:
2664 hci_remote_ext_features_evt(hdev, skb);
2665 break;
2666
2667 case HCI_EV_SYNC_CONN_COMPLETE:
2668 hci_sync_conn_complete_evt(hdev, skb);
2669 break;
2670
2671 case HCI_EV_SYNC_CONN_CHANGED:
2672 hci_sync_conn_changed_evt(hdev, skb);
2673 break;
2674
Marcel Holtmann04837f62006-07-03 10:02:33 +02002675 case HCI_EV_SNIFF_SUBRATE:
2676 hci_sniff_subrate_evt(hdev, skb);
2677 break;
2678
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002679 case HCI_EV_EXTENDED_INQUIRY_RESULT:
2680 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002681 break;
2682
Marcel Holtmann04936842008-07-14 20:13:48 +02002683 case HCI_EV_IO_CAPA_REQUEST:
2684 hci_io_capa_request_evt(hdev, skb);
2685 break;
2686
Johan Hedberg03b555e2011-01-04 15:40:05 +02002687 case HCI_EV_IO_CAPA_REPLY:
2688 hci_io_capa_reply_evt(hdev, skb);
2689 break;
2690
Johan Hedberga5c29682011-02-19 12:05:57 -03002691 case HCI_EV_USER_CONFIRM_REQUEST:
2692 hci_user_confirm_request_evt(hdev, skb);
2693 break;
2694
Marcel Holtmann04936842008-07-14 20:13:48 +02002695 case HCI_EV_SIMPLE_PAIR_COMPLETE:
2696 hci_simple_pair_complete_evt(hdev, skb);
2697 break;
2698
Marcel Holtmann41a96212008-07-14 20:13:48 +02002699 case HCI_EV_REMOTE_HOST_FEATURES:
2700 hci_remote_host_features_evt(hdev, skb);
2701 break;
2702
Ville Tervofcd89c02011-02-10 22:38:47 -03002703 case HCI_EV_LE_META:
2704 hci_le_meta_evt(hdev, skb);
2705 break;
2706
Szymon Janc2763eda2011-03-22 13:12:22 +01002707 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
2708 hci_remote_oob_data_request_evt(hdev, skb);
2709 break;
2710
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002711 default:
2712 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002713 break;
2714 }
2715
2716 kfree_skb(skb);
2717 hdev->stat.evt_rx++;
2718}
2719
2720/* Generate internal stack event */
2721void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
2722{
2723 struct hci_event_hdr *hdr;
2724 struct hci_ev_stack_internal *ev;
2725 struct sk_buff *skb;
2726
2727 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
2728 if (!skb)
2729 return;
2730
2731 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
2732 hdr->evt = HCI_EV_STACK_INTERNAL;
2733 hdr->plen = sizeof(*ev) + dlen;
2734
2735 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
2736 ev->type = type;
2737 memcpy(ev->data, data, dlen);
2738
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002739 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07002740 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002741
Marcel Holtmann0d48d932005-08-09 20:30:28 -07002742 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002743 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02002744 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745 kfree_skb(skb);
2746}