blob: d04011c06be006a3c9c2a321b78c7cbfbbb0eb35 [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
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300186 clear_bit(HCI_RESET, &hdev->flags);
187
Johan Hedberg23bb5762010-12-21 23:01:27 +0200188 hci_req_complete(hdev, HCI_OP_RESET, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200189}
190
191static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
192{
193 __u8 status = *((__u8 *) skb->data);
194 void *sent;
195
196 BT_DBG("%s status 0x%x", hdev->name, status);
197
198 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
199 if (!sent)
200 return;
201
Johan Hedbergb312b1612011-03-16 14:29:37 +0200202 if (test_bit(HCI_MGMT, &hdev->flags))
203 mgmt_set_local_name_complete(hdev->id, sent, status);
204
205 if (status)
206 return;
207
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200208 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200209}
210
211static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
212{
213 struct hci_rp_read_local_name *rp = (void *) skb->data;
214
215 BT_DBG("%s status 0x%x", hdev->name, rp->status);
216
217 if (rp->status)
218 return;
219
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200220 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200221}
222
223static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
224{
225 __u8 status = *((__u8 *) skb->data);
226 void *sent;
227
228 BT_DBG("%s status 0x%x", hdev->name, status);
229
230 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
231 if (!sent)
232 return;
233
234 if (!status) {
235 __u8 param = *((__u8 *) sent);
236
237 if (param == AUTH_ENABLED)
238 set_bit(HCI_AUTH, &hdev->flags);
239 else
240 clear_bit(HCI_AUTH, &hdev->flags);
241 }
242
Johan Hedberg23bb5762010-12-21 23:01:27 +0200243 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200244}
245
246static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
247{
248 __u8 status = *((__u8 *) skb->data);
249 void *sent;
250
251 BT_DBG("%s status 0x%x", hdev->name, status);
252
253 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
254 if (!sent)
255 return;
256
257 if (!status) {
258 __u8 param = *((__u8 *) sent);
259
260 if (param)
261 set_bit(HCI_ENCRYPT, &hdev->flags);
262 else
263 clear_bit(HCI_ENCRYPT, &hdev->flags);
264 }
265
Johan Hedberg23bb5762010-12-21 23:01:27 +0200266 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200267}
268
269static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
270{
271 __u8 status = *((__u8 *) skb->data);
272 void *sent;
273
274 BT_DBG("%s status 0x%x", hdev->name, status);
275
276 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
277 if (!sent)
278 return;
279
280 if (!status) {
281 __u8 param = *((__u8 *) sent);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200282 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200283
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200284 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
285 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200286
Johan Hedberg73f22f62010-12-29 16:00:25 +0200287 if (param & SCAN_INQUIRY) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200288 set_bit(HCI_ISCAN, &hdev->flags);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200289 if (!old_iscan)
290 mgmt_discoverable(hdev->id, 1);
291 } else if (old_iscan)
Johan Hedberg73f22f62010-12-29 16:00:25 +0200292 mgmt_discoverable(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200293
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200294 if (param & SCAN_PAGE) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200295 set_bit(HCI_PSCAN, &hdev->flags);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200296 if (!old_pscan)
297 mgmt_connectable(hdev->id, 1);
298 } else if (old_pscan)
299 mgmt_connectable(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200300 }
301
Johan Hedberg23bb5762010-12-21 23:01:27 +0200302 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200303}
304
305static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
306{
307 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
308
309 BT_DBG("%s status 0x%x", hdev->name, rp->status);
310
311 if (rp->status)
312 return;
313
314 memcpy(hdev->dev_class, rp->dev_class, 3);
315
316 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
317 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
318}
319
320static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
321{
322 __u8 status = *((__u8 *) skb->data);
323 void *sent;
324
325 BT_DBG("%s status 0x%x", hdev->name, status);
326
Marcel Holtmannf383f272008-07-14 20:13:47 +0200327 if (status)
328 return;
329
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200330 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
331 if (!sent)
332 return;
333
Marcel Holtmannf383f272008-07-14 20:13:47 +0200334 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200335}
336
337static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
338{
339 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200341
342 BT_DBG("%s status 0x%x", hdev->name, rp->status);
343
344 if (rp->status)
345 return;
346
347 setting = __le16_to_cpu(rp->voice_setting);
348
Marcel Holtmannf383f272008-07-14 20:13:47 +0200349 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200350 return;
351
352 hdev->voice_setting = setting;
353
354 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
355
356 if (hdev->notify) {
357 tasklet_disable(&hdev->tx_task);
358 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
359 tasklet_enable(&hdev->tx_task);
360 }
361}
362
363static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
364{
365 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200366 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 void *sent;
368
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200369 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370
Marcel Holtmannf383f272008-07-14 20:13:47 +0200371 if (status)
372 return;
373
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200374 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
375 if (!sent)
376 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377
Marcel Holtmannf383f272008-07-14 20:13:47 +0200378 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379
Marcel Holtmannf383f272008-07-14 20:13:47 +0200380 if (hdev->voice_setting == setting)
381 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
Marcel Holtmannf383f272008-07-14 20:13:47 +0200383 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384
Marcel Holtmannf383f272008-07-14 20:13:47 +0200385 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
386
387 if (hdev->notify) {
388 tasklet_disable(&hdev->tx_task);
389 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
390 tasklet_enable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 }
392}
393
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200394static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200396 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200398 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399
Johan Hedberg23bb5762010-12-21 23:01:27 +0200400 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401}
402
Marcel Holtmann333140b2008-07-14 20:13:48 +0200403static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
404{
405 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
406
407 BT_DBG("%s status 0x%x", hdev->name, rp->status);
408
409 if (rp->status)
410 return;
411
412 hdev->ssp_mode = rp->mode;
413}
414
415static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
416{
417 __u8 status = *((__u8 *) skb->data);
418 void *sent;
419
420 BT_DBG("%s status 0x%x", hdev->name, status);
421
422 if (status)
423 return;
424
425 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
426 if (!sent)
427 return;
428
429 hdev->ssp_mode = *((__u8 *) sent);
430}
431
Johan Hedbergd5859e22011-01-25 01:19:58 +0200432static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
433{
434 if (hdev->features[6] & LMP_EXT_INQ)
435 return 2;
436
437 if (hdev->features[3] & LMP_RSSI_INQ)
438 return 1;
439
440 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
441 hdev->lmp_subver == 0x0757)
442 return 1;
443
444 if (hdev->manufacturer == 15) {
445 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
446 return 1;
447 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
448 return 1;
449 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
450 return 1;
451 }
452
453 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
454 hdev->lmp_subver == 0x1805)
455 return 1;
456
457 return 0;
458}
459
460static void hci_setup_inquiry_mode(struct hci_dev *hdev)
461{
462 u8 mode;
463
464 mode = hci_get_inquiry_mode(hdev);
465
466 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
467}
468
469static void hci_setup_event_mask(struct hci_dev *hdev)
470{
471 /* The second byte is 0xff instead of 0x9f (two reserved bits
472 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
473 * command otherwise */
474 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
475
476 /* Events for 1.2 and newer controllers */
477 if (hdev->lmp_ver > 1) {
478 events[4] |= 0x01; /* Flow Specification Complete */
479 events[4] |= 0x02; /* Inquiry Result with RSSI */
480 events[4] |= 0x04; /* Read Remote Extended Features Complete */
481 events[5] |= 0x08; /* Synchronous Connection Complete */
482 events[5] |= 0x10; /* Synchronous Connection Changed */
483 }
484
485 if (hdev->features[3] & LMP_RSSI_INQ)
486 events[4] |= 0x04; /* Inquiry Result with RSSI */
487
488 if (hdev->features[5] & LMP_SNIFF_SUBR)
489 events[5] |= 0x20; /* Sniff Subrating */
490
491 if (hdev->features[5] & LMP_PAUSE_ENC)
492 events[5] |= 0x80; /* Encryption Key Refresh Complete */
493
494 if (hdev->features[6] & LMP_EXT_INQ)
495 events[5] |= 0x40; /* Extended Inquiry Result */
496
497 if (hdev->features[6] & LMP_NO_FLUSH)
498 events[7] |= 0x01; /* Enhanced Flush Complete */
499
500 if (hdev->features[7] & LMP_LSTO)
501 events[6] |= 0x80; /* Link Supervision Timeout Changed */
502
503 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
504 events[6] |= 0x01; /* IO Capability Request */
505 events[6] |= 0x02; /* IO Capability Response */
506 events[6] |= 0x04; /* User Confirmation Request */
507 events[6] |= 0x08; /* User Passkey Request */
508 events[6] |= 0x10; /* Remote OOB Data Request */
509 events[6] |= 0x20; /* Simple Pairing Complete */
510 events[7] |= 0x04; /* User Passkey Notification */
511 events[7] |= 0x08; /* Keypress Notification */
512 events[7] |= 0x10; /* Remote Host Supported
513 * Features Notification */
514 }
515
516 if (hdev->features[4] & LMP_LE)
517 events[7] |= 0x20; /* LE Meta-Event */
518
519 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
520}
521
522static void hci_setup(struct hci_dev *hdev)
523{
524 hci_setup_event_mask(hdev);
525
526 if (hdev->lmp_ver > 1)
527 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
528
529 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
530 u8 mode = 0x01;
531 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
532 }
533
534 if (hdev->features[3] & LMP_RSSI_INQ)
535 hci_setup_inquiry_mode(hdev);
536
537 if (hdev->features[7] & LMP_INQ_TX_PWR)
538 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
539}
540
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200541static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
542{
543 struct hci_rp_read_local_version *rp = (void *) skb->data;
544
545 BT_DBG("%s status 0x%x", hdev->name, rp->status);
546
547 if (rp->status)
548 return;
549
550 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200551 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200552 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200553 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200554 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200555
556 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
557 hdev->manufacturer,
558 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200559
560 if (test_bit(HCI_INIT, &hdev->flags))
561 hci_setup(hdev);
562}
563
564static void hci_setup_link_policy(struct hci_dev *hdev)
565{
566 u16 link_policy = 0;
567
568 if (hdev->features[0] & LMP_RSWITCH)
569 link_policy |= HCI_LP_RSWITCH;
570 if (hdev->features[0] & LMP_HOLD)
571 link_policy |= HCI_LP_HOLD;
572 if (hdev->features[0] & LMP_SNIFF)
573 link_policy |= HCI_LP_SNIFF;
574 if (hdev->features[1] & LMP_PARK)
575 link_policy |= HCI_LP_PARK;
576
577 link_policy = cpu_to_le16(link_policy);
578 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
579 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200580}
581
582static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
583{
584 struct hci_rp_read_local_commands *rp = (void *) skb->data;
585
586 BT_DBG("%s status 0x%x", hdev->name, rp->status);
587
588 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200589 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200590
591 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200592
593 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
594 hci_setup_link_policy(hdev);
595
596done:
597 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200598}
599
600static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
601{
602 struct hci_rp_read_local_features *rp = (void *) skb->data;
603
604 BT_DBG("%s status 0x%x", hdev->name, rp->status);
605
606 if (rp->status)
607 return;
608
609 memcpy(hdev->features, rp->features, 8);
610
611 /* Adjust default settings according to features
612 * supported by device. */
613
614 if (hdev->features[0] & LMP_3SLOT)
615 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
616
617 if (hdev->features[0] & LMP_5SLOT)
618 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
619
620 if (hdev->features[1] & LMP_HV2) {
621 hdev->pkt_type |= (HCI_HV2);
622 hdev->esco_type |= (ESCO_HV2);
623 }
624
625 if (hdev->features[1] & LMP_HV3) {
626 hdev->pkt_type |= (HCI_HV3);
627 hdev->esco_type |= (ESCO_HV3);
628 }
629
630 if (hdev->features[3] & LMP_ESCO)
631 hdev->esco_type |= (ESCO_EV3);
632
633 if (hdev->features[4] & LMP_EV4)
634 hdev->esco_type |= (ESCO_EV4);
635
636 if (hdev->features[4] & LMP_EV5)
637 hdev->esco_type |= (ESCO_EV5);
638
Marcel Holtmannefc76882009-02-06 09:13:37 +0100639 if (hdev->features[5] & LMP_EDR_ESCO_2M)
640 hdev->esco_type |= (ESCO_2EV3);
641
642 if (hdev->features[5] & LMP_EDR_ESCO_3M)
643 hdev->esco_type |= (ESCO_3EV3);
644
645 if (hdev->features[5] & LMP_EDR_3S_ESCO)
646 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
647
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200648 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
649 hdev->features[0], hdev->features[1],
650 hdev->features[2], hdev->features[3],
651 hdev->features[4], hdev->features[5],
652 hdev->features[6], hdev->features[7]);
653}
654
655static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
656{
657 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
658
659 BT_DBG("%s status 0x%x", hdev->name, rp->status);
660
661 if (rp->status)
662 return;
663
664 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
665 hdev->sco_mtu = rp->sco_mtu;
666 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
667 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
668
669 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
670 hdev->sco_mtu = 64;
671 hdev->sco_pkts = 8;
672 }
673
674 hdev->acl_cnt = hdev->acl_pkts;
675 hdev->sco_cnt = hdev->sco_pkts;
676
677 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
678 hdev->acl_mtu, hdev->acl_pkts,
679 hdev->sco_mtu, hdev->sco_pkts);
680}
681
682static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
683{
684 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
685
686 BT_DBG("%s status 0x%x", hdev->name, rp->status);
687
688 if (!rp->status)
689 bacpy(&hdev->bdaddr, &rp->bdaddr);
690
Johan Hedberg23bb5762010-12-21 23:01:27 +0200691 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
692}
693
694static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
695{
696 __u8 status = *((__u8 *) skb->data);
697
698 BT_DBG("%s status 0x%x", hdev->name, status);
699
700 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200701}
702
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200703static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
704 struct sk_buff *skb)
705{
706 __u8 status = *((__u8 *) skb->data);
707
708 BT_DBG("%s status 0x%x", hdev->name, status);
709
710 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
711}
712
Johan Hedbergd5859e22011-01-25 01:19:58 +0200713static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
714{
715 __u8 status = *((__u8 *) skb->data);
716
717 BT_DBG("%s status 0x%x", hdev->name, status);
718
719 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
720}
721
722static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
723 struct sk_buff *skb)
724{
725 __u8 status = *((__u8 *) skb->data);
726
727 BT_DBG("%s status 0x%x", hdev->name, status);
728
729 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
730}
731
732static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
733 struct sk_buff *skb)
734{
735 __u8 status = *((__u8 *) skb->data);
736
737 BT_DBG("%s status 0x%x", hdev->name, status);
738
739 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
740}
741
742static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
743{
744 __u8 status = *((__u8 *) skb->data);
745
746 BT_DBG("%s status 0x%x", hdev->name, status);
747
748 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
749}
750
Johan Hedberg980e1a52011-01-22 06:10:07 +0200751static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
752{
753 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
754 struct hci_cp_pin_code_reply *cp;
755 struct hci_conn *conn;
756
757 BT_DBG("%s status 0x%x", hdev->name, rp->status);
758
759 if (test_bit(HCI_MGMT, &hdev->flags))
760 mgmt_pin_code_reply_complete(hdev->id, &rp->bdaddr, rp->status);
761
762 if (rp->status != 0)
763 return;
764
765 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
766 if (!cp)
767 return;
768
769 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
770 if (conn)
771 conn->pin_length = cp->pin_len;
772}
773
774static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
775{
776 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
777
778 BT_DBG("%s status 0x%x", hdev->name, rp->status);
779
780 if (test_bit(HCI_MGMT, &hdev->flags))
781 mgmt_pin_code_neg_reply_complete(hdev->id, &rp->bdaddr,
782 rp->status);
783}
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300784static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
785 struct sk_buff *skb)
786{
787 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
788
789 BT_DBG("%s status 0x%x", hdev->name, rp->status);
790
791 if (rp->status)
792 return;
793
794 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
795 hdev->le_pkts = rp->le_max_pkt;
796
797 hdev->le_cnt = hdev->le_pkts;
798
799 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
800
801 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
802}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200803
Johan Hedberga5c29682011-02-19 12:05:57 -0300804static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
805{
806 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
807
808 BT_DBG("%s status 0x%x", hdev->name, rp->status);
809
810 if (test_bit(HCI_MGMT, &hdev->flags))
811 mgmt_user_confirm_reply_complete(hdev->id, &rp->bdaddr,
812 rp->status);
813}
814
815static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
816 struct sk_buff *skb)
817{
818 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
819
820 BT_DBG("%s status 0x%x", hdev->name, rp->status);
821
822 if (test_bit(HCI_MGMT, &hdev->flags))
823 mgmt_user_confirm_neg_reply_complete(hdev->id, &rp->bdaddr,
824 rp->status);
825}
826
Szymon Jancc35938b2011-03-22 13:12:21 +0100827static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
828 struct sk_buff *skb)
829{
830 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
831
832 BT_DBG("%s status 0x%x", hdev->name, rp->status);
833
834 mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
835 rp->randomizer, rp->status);
836}
837
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200838static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
839{
840 BT_DBG("%s status 0x%x", hdev->name, status);
841
842 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +0200843 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200844
845 hci_conn_check_pending(hdev);
846 } else
847 set_bit(HCI_INQUIRY, &hdev->flags);
848}
849
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
851{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200852 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200855 BT_DBG("%s status 0x%x", hdev->name, status);
856
857 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858 if (!cp)
859 return;
860
861 hci_dev_lock(hdev);
862
863 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
864
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200865 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866
867 if (status) {
868 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200869 if (status != 0x0c || conn->attempt > 2) {
870 conn->state = BT_CLOSED;
871 hci_proto_connect_cfm(conn, status);
872 hci_conn_del(conn);
873 } else
874 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 }
876 } else {
877 if (!conn) {
878 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
879 if (conn) {
880 conn->out = 1;
881 conn->link_mode |= HCI_LM_MASTER;
882 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -0300883 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 }
885 }
886
887 hci_dev_unlock(hdev);
888}
889
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200890static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200892 struct hci_cp_add_sco *cp;
893 struct hci_conn *acl, *sco;
894 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200896 BT_DBG("%s status 0x%x", hdev->name, status);
897
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200898 if (!status)
899 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200901 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
902 if (!cp)
903 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200905 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200907 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100908
909 hci_dev_lock(hdev);
910
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200911 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200912 if (acl) {
913 sco = acl->link;
914 if (sco) {
915 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200916
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200917 hci_proto_connect_cfm(sco, status);
918 hci_conn_del(sco);
919 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200920 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100921
922 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923}
924
Marcel Holtmannf8558552008-07-14 20:13:49 +0200925static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
926{
927 struct hci_cp_auth_requested *cp;
928 struct hci_conn *conn;
929
930 BT_DBG("%s status 0x%x", hdev->name, status);
931
932 if (!status)
933 return;
934
935 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
936 if (!cp)
937 return;
938
939 hci_dev_lock(hdev);
940
941 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
942 if (conn) {
943 if (conn->state == BT_CONFIG) {
944 hci_proto_connect_cfm(conn, status);
945 hci_conn_put(conn);
946 }
947 }
948
949 hci_dev_unlock(hdev);
950}
951
952static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
953{
954 struct hci_cp_set_conn_encrypt *cp;
955 struct hci_conn *conn;
956
957 BT_DBG("%s status 0x%x", hdev->name, status);
958
959 if (!status)
960 return;
961
962 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
963 if (!cp)
964 return;
965
966 hci_dev_lock(hdev);
967
968 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
969 if (conn) {
970 if (conn->state == BT_CONFIG) {
971 hci_proto_connect_cfm(conn, status);
972 hci_conn_put(conn);
973 }
974 }
975
976 hci_dev_unlock(hdev);
977}
978
Johan Hedberg127178d2010-11-18 22:22:29 +0200979static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +0100980 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +0200981{
Johan Hedberg392599b2010-11-18 22:22:28 +0200982 if (conn->state != BT_CONFIG || !conn->out)
983 return 0;
984
Johan Hedberg765c2a92011-01-19 12:06:52 +0530985 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +0200986 return 0;
987
988 /* Only request authentication for SSP connections or non-SSP
989 * devices with sec_level HIGH */
990 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Johan Hedberg765c2a92011-01-19 12:06:52 +0530991 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +0200992 return 0;
993
Johan Hedberg392599b2010-11-18 22:22:28 +0200994 return 1;
995}
996
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200997static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
998{
Johan Hedberg127178d2010-11-18 22:22:29 +0200999 struct hci_cp_remote_name_req *cp;
1000 struct hci_conn *conn;
1001
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001002 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001003
1004 /* If successful wait for the name req complete event before
1005 * checking for the need to do authentication */
1006 if (!status)
1007 return;
1008
1009 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1010 if (!cp)
1011 return;
1012
1013 hci_dev_lock(hdev);
1014
1015 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1016 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1017 struct hci_cp_auth_requested cp;
1018 cp.handle = __cpu_to_le16(conn->handle);
1019 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1020 }
1021
1022 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001023}
1024
Marcel Holtmann769be972008-07-14 20:13:49 +02001025static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1026{
1027 struct hci_cp_read_remote_features *cp;
1028 struct hci_conn *conn;
1029
1030 BT_DBG("%s status 0x%x", hdev->name, status);
1031
1032 if (!status)
1033 return;
1034
1035 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1036 if (!cp)
1037 return;
1038
1039 hci_dev_lock(hdev);
1040
1041 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1042 if (conn) {
1043 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001044 hci_proto_connect_cfm(conn, status);
1045 hci_conn_put(conn);
1046 }
1047 }
1048
1049 hci_dev_unlock(hdev);
1050}
1051
1052static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1053{
1054 struct hci_cp_read_remote_ext_features *cp;
1055 struct hci_conn *conn;
1056
1057 BT_DBG("%s status 0x%x", hdev->name, status);
1058
1059 if (!status)
1060 return;
1061
1062 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1063 if (!cp)
1064 return;
1065
1066 hci_dev_lock(hdev);
1067
1068 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1069 if (conn) {
1070 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001071 hci_proto_connect_cfm(conn, status);
1072 hci_conn_put(conn);
1073 }
1074 }
1075
1076 hci_dev_unlock(hdev);
1077}
1078
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001079static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1080{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001081 struct hci_cp_setup_sync_conn *cp;
1082 struct hci_conn *acl, *sco;
1083 __u16 handle;
1084
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001085 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001086
1087 if (!status)
1088 return;
1089
1090 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1091 if (!cp)
1092 return;
1093
1094 handle = __le16_to_cpu(cp->handle);
1095
1096 BT_DBG("%s handle %d", hdev->name, handle);
1097
1098 hci_dev_lock(hdev);
1099
1100 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001101 if (acl) {
1102 sco = acl->link;
1103 if (sco) {
1104 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001105
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001106 hci_proto_connect_cfm(sco, status);
1107 hci_conn_del(sco);
1108 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001109 }
1110
1111 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001112}
1113
1114static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1115{
1116 struct hci_cp_sniff_mode *cp;
1117 struct hci_conn *conn;
1118
1119 BT_DBG("%s status 0x%x", hdev->name, status);
1120
1121 if (!status)
1122 return;
1123
1124 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1125 if (!cp)
1126 return;
1127
1128 hci_dev_lock(hdev);
1129
1130 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001131 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001132 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1133
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001134 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1135 hci_sco_setup(conn, status);
1136 }
1137
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001138 hci_dev_unlock(hdev);
1139}
1140
1141static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1142{
1143 struct hci_cp_exit_sniff_mode *cp;
1144 struct hci_conn *conn;
1145
1146 BT_DBG("%s status 0x%x", hdev->name, status);
1147
1148 if (!status)
1149 return;
1150
1151 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1152 if (!cp)
1153 return;
1154
1155 hci_dev_lock(hdev);
1156
1157 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001158 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001159 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1160
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001161 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1162 hci_sco_setup(conn, status);
1163 }
1164
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001165 hci_dev_unlock(hdev);
1166}
1167
Ville Tervofcd89c02011-02-10 22:38:47 -03001168static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1169{
1170 struct hci_cp_le_create_conn *cp;
1171 struct hci_conn *conn;
1172
1173 BT_DBG("%s status 0x%x", hdev->name, status);
1174
1175 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1176 if (!cp)
1177 return;
1178
1179 hci_dev_lock(hdev);
1180
1181 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1182
1183 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1184 conn);
1185
1186 if (status) {
1187 if (conn && conn->state == BT_CONNECT) {
1188 conn->state = BT_CLOSED;
1189 hci_proto_connect_cfm(conn, status);
1190 hci_conn_del(conn);
1191 }
1192 } else {
1193 if (!conn) {
1194 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
1195 if (conn)
1196 conn->out = 1;
1197 else
1198 BT_ERR("No memory for new connection");
1199 }
1200 }
1201
1202 hci_dev_unlock(hdev);
1203}
1204
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001205static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1206{
1207 __u8 status = *((__u8 *) skb->data);
1208
1209 BT_DBG("%s status %d", hdev->name, status);
1210
1211 clear_bit(HCI_INQUIRY, &hdev->flags);
1212
Johan Hedberg23bb5762010-12-21 23:01:27 +02001213 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001214
1215 hci_conn_check_pending(hdev);
1216}
1217
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1219{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001220 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001221 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 int num_rsp = *((__u8 *) skb->data);
1223
1224 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1225
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001226 if (!num_rsp)
1227 return;
1228
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001230
Johan Hedberge17acd42011-03-30 23:57:16 +03001231 for (; num_rsp; num_rsp--, info++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 bacpy(&data.bdaddr, &info->bdaddr);
1233 data.pscan_rep_mode = info->pscan_rep_mode;
1234 data.pscan_period_mode = info->pscan_period_mode;
1235 data.pscan_mode = info->pscan_mode;
1236 memcpy(data.dev_class, info->dev_class, 3);
1237 data.clock_offset = info->clock_offset;
1238 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001239 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 hci_inquiry_cache_update(hdev, &data);
Johan Hedberge17acd42011-03-30 23:57:16 +03001241 mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class, 0,
1242 NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001244
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 hci_dev_unlock(hdev);
1246}
1247
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001248static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001250 struct hci_ev_conn_complete *ev = (void *) skb->data;
1251 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001253 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001254
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001256
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001257 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001258 if (!conn) {
1259 if (ev->link_type != SCO_LINK)
1260 goto unlock;
1261
1262 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1263 if (!conn)
1264 goto unlock;
1265
1266 conn->type = SCO_LINK;
1267 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001268
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001269 if (!ev->status) {
1270 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001271
1272 if (conn->type == ACL_LINK) {
1273 conn->state = BT_CONFIG;
1274 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001275 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedbergf7520542011-01-20 12:34:39 +02001276 mgmt_connected(hdev->id, &ev->bdaddr);
Marcel Holtmann769be972008-07-14 20:13:49 +02001277 } else
1278 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001279
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001280 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001281 hci_conn_add_sysfs(conn);
1282
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001283 if (test_bit(HCI_AUTH, &hdev->flags))
1284 conn->link_mode |= HCI_LM_AUTH;
1285
1286 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1287 conn->link_mode |= HCI_LM_ENCRYPT;
1288
1289 /* Get remote features */
1290 if (conn->type == ACL_LINK) {
1291 struct hci_cp_read_remote_features cp;
1292 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001293 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1294 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001295 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001296
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001297 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +02001298 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001299 struct hci_cp_change_conn_ptype cp;
1300 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001301 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1302 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1303 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001304 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001305 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001306 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001307 if (conn->type == ACL_LINK)
1308 mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status);
1309 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001310
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001311 if (conn->type == ACL_LINK)
1312 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001313
Marcel Holtmann769be972008-07-14 20:13:49 +02001314 if (ev->status) {
1315 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001316 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001317 } else if (ev->link_type != ACL_LINK)
1318 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001319
1320unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001322
1323 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324}
1325
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1327{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001328 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329 int mask = hdev->link_mode;
1330
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001331 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1332 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333
1334 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1335
Szymon Janc138d22e2011-02-17 16:44:23 +01001336 if ((mask & HCI_LM_ACCEPT) &&
1337 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001339 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341
1342 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001343
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001344 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1345 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001346 memcpy(ie->data.dev_class, ev->dev_class, 3);
1347
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1349 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001350 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1351 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001352 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353 hci_dev_unlock(hdev);
1354 return;
1355 }
1356 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001357
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358 memcpy(conn->dev_class, ev->dev_class, 3);
1359 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001360
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361 hci_dev_unlock(hdev);
1362
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001363 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1364 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001366 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001368 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1369 cp.role = 0x00; /* Become master */
1370 else
1371 cp.role = 0x01; /* Remain slave */
1372
1373 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1374 sizeof(cp), &cp);
1375 } else {
1376 struct hci_cp_accept_sync_conn_req cp;
1377
1378 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001379 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001380
1381 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1382 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1383 cp.max_latency = cpu_to_le16(0xffff);
1384 cp.content_format = cpu_to_le16(hdev->voice_setting);
1385 cp.retrans_effort = 0xff;
1386
1387 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1388 sizeof(cp), &cp);
1389 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390 } else {
1391 /* Connection rejected */
1392 struct hci_cp_reject_conn_req cp;
1393
1394 bacpy(&cp.bdaddr, &ev->bdaddr);
1395 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001396 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 }
1398}
1399
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1401{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001402 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001403 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
1405 BT_DBG("%s status %d", hdev->name, ev->status);
1406
Johan Hedberg8962ee72011-01-20 12:40:27 +02001407 if (ev->status) {
1408 mgmt_disconnect_failed(hdev->id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 return;
Johan Hedberg8962ee72011-01-20 12:40:27 +02001410 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411
1412 hci_dev_lock(hdev);
1413
Marcel Holtmann04837f62006-07-03 10:02:33 +02001414 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001415 if (!conn)
1416 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001417
Johan Hedbergf7520542011-01-20 12:34:39 +02001418 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419
Johan Hedbergf7520542011-01-20 12:34:39 +02001420 if (conn->type == ACL_LINK)
1421 mgmt_disconnected(hdev->id, &conn->dst);
1422
1423 hci_proto_disconn_cfm(conn, ev->reason);
1424 hci_conn_del(conn);
1425
1426unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427 hci_dev_unlock(hdev);
1428}
1429
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001430static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1431{
1432 struct hci_ev_auth_complete *ev = (void *) skb->data;
1433 struct hci_conn *conn;
1434
1435 BT_DBG("%s status %d", hdev->name, ev->status);
1436
1437 hci_dev_lock(hdev);
1438
1439 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1440 if (conn) {
Johan Hedberg765c2a92011-01-19 12:06:52 +05301441 if (!ev->status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001442 conn->link_mode |= HCI_LM_AUTH;
Johan Hedberg765c2a92011-01-19 12:06:52 +05301443 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001444 } else {
1445 mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
Johan Hedbergda213f42010-06-18 11:08:56 +03001446 conn->sec_level = BT_SECURITY_LOW;
Johan Hedberg2a611692011-02-19 12:06:00 -03001447 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001448
1449 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1450
Marcel Holtmannf8558552008-07-14 20:13:49 +02001451 if (conn->state == BT_CONFIG) {
1452 if (!ev->status && hdev->ssp_mode > 0 &&
1453 conn->ssp_mode > 0) {
1454 struct hci_cp_set_conn_encrypt cp;
1455 cp.handle = ev->handle;
1456 cp.encrypt = 0x01;
1457 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1458 sizeof(cp), &cp);
1459 } else {
1460 conn->state = BT_CONNECTED;
1461 hci_proto_connect_cfm(conn, ev->status);
1462 hci_conn_put(conn);
1463 }
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001464 } else {
Marcel Holtmannf8558552008-07-14 20:13:49 +02001465 hci_auth_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001466
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001467 hci_conn_hold(conn);
1468 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1469 hci_conn_put(conn);
1470 }
1471
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001472 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1473 if (!ev->status) {
1474 struct hci_cp_set_conn_encrypt cp;
Marcel Holtmannf8558552008-07-14 20:13:49 +02001475 cp.handle = ev->handle;
1476 cp.encrypt = 0x01;
1477 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1478 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001479 } else {
1480 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1481 hci_encrypt_cfm(conn, ev->status, 0x00);
1482 }
1483 }
1484 }
1485
1486 hci_dev_unlock(hdev);
1487}
1488
1489static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1490{
Johan Hedberg127178d2010-11-18 22:22:29 +02001491 struct hci_ev_remote_name *ev = (void *) skb->data;
1492 struct hci_conn *conn;
1493
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001494 BT_DBG("%s", hdev->name);
1495
1496 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001497
1498 hci_dev_lock(hdev);
1499
1500 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1501 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1502 struct hci_cp_auth_requested cp;
1503 cp.handle = __cpu_to_le16(conn->handle);
1504 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1505 }
1506
1507 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001508}
1509
1510static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1511{
1512 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1513 struct hci_conn *conn;
1514
1515 BT_DBG("%s status %d", hdev->name, ev->status);
1516
1517 hci_dev_lock(hdev);
1518
1519 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1520 if (conn) {
1521 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001522 if (ev->encrypt) {
1523 /* Encryption implies authentication */
1524 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001525 conn->link_mode |= HCI_LM_ENCRYPT;
Marcel Holtmannae293192008-07-14 20:13:45 +02001526 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001527 conn->link_mode &= ~HCI_LM_ENCRYPT;
1528 }
1529
1530 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1531
Marcel Holtmannf8558552008-07-14 20:13:49 +02001532 if (conn->state == BT_CONFIG) {
1533 if (!ev->status)
1534 conn->state = BT_CONNECTED;
1535
1536 hci_proto_connect_cfm(conn, ev->status);
1537 hci_conn_put(conn);
1538 } else
1539 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001540 }
1541
1542 hci_dev_unlock(hdev);
1543}
1544
1545static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1546{
1547 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1548 struct hci_conn *conn;
1549
1550 BT_DBG("%s status %d", hdev->name, ev->status);
1551
1552 hci_dev_lock(hdev);
1553
1554 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1555 if (conn) {
1556 if (!ev->status)
1557 conn->link_mode |= HCI_LM_SECURE;
1558
1559 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1560
1561 hci_key_change_cfm(conn, ev->status);
1562 }
1563
1564 hci_dev_unlock(hdev);
1565}
1566
1567static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1568{
1569 struct hci_ev_remote_features *ev = (void *) skb->data;
1570 struct hci_conn *conn;
1571
1572 BT_DBG("%s status %d", hdev->name, ev->status);
1573
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001574 hci_dev_lock(hdev);
1575
1576 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001577 if (!conn)
1578 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001579
Johan Hedbergccd556f2010-11-10 17:11:51 +02001580 if (!ev->status)
1581 memcpy(conn->features, ev->features, 8);
1582
1583 if (conn->state != BT_CONFIG)
1584 goto unlock;
1585
1586 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1587 struct hci_cp_read_remote_ext_features cp;
1588 cp.handle = ev->handle;
1589 cp.page = 0x01;
1590 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001591 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001592 goto unlock;
1593 }
1594
Johan Hedberg127178d2010-11-18 22:22:29 +02001595 if (!ev->status) {
1596 struct hci_cp_remote_name_req cp;
1597 memset(&cp, 0, sizeof(cp));
1598 bacpy(&cp.bdaddr, &conn->dst);
1599 cp.pscan_rep_mode = 0x02;
1600 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1601 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001602
Johan Hedberg127178d2010-11-18 22:22:29 +02001603 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001604 conn->state = BT_CONNECTED;
1605 hci_proto_connect_cfm(conn, ev->status);
1606 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001607 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001608
Johan Hedbergccd556f2010-11-10 17:11:51 +02001609unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001610 hci_dev_unlock(hdev);
1611}
1612
1613static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1614{
1615 BT_DBG("%s", hdev->name);
1616}
1617
1618static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1619{
1620 BT_DBG("%s", hdev->name);
1621}
1622
1623static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1624{
1625 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1626 __u16 opcode;
1627
1628 skb_pull(skb, sizeof(*ev));
1629
1630 opcode = __le16_to_cpu(ev->opcode);
1631
1632 switch (opcode) {
1633 case HCI_OP_INQUIRY_CANCEL:
1634 hci_cc_inquiry_cancel(hdev, skb);
1635 break;
1636
1637 case HCI_OP_EXIT_PERIODIC_INQ:
1638 hci_cc_exit_periodic_inq(hdev, skb);
1639 break;
1640
1641 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1642 hci_cc_remote_name_req_cancel(hdev, skb);
1643 break;
1644
1645 case HCI_OP_ROLE_DISCOVERY:
1646 hci_cc_role_discovery(hdev, skb);
1647 break;
1648
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001649 case HCI_OP_READ_LINK_POLICY:
1650 hci_cc_read_link_policy(hdev, skb);
1651 break;
1652
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001653 case HCI_OP_WRITE_LINK_POLICY:
1654 hci_cc_write_link_policy(hdev, skb);
1655 break;
1656
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001657 case HCI_OP_READ_DEF_LINK_POLICY:
1658 hci_cc_read_def_link_policy(hdev, skb);
1659 break;
1660
1661 case HCI_OP_WRITE_DEF_LINK_POLICY:
1662 hci_cc_write_def_link_policy(hdev, skb);
1663 break;
1664
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001665 case HCI_OP_RESET:
1666 hci_cc_reset(hdev, skb);
1667 break;
1668
1669 case HCI_OP_WRITE_LOCAL_NAME:
1670 hci_cc_write_local_name(hdev, skb);
1671 break;
1672
1673 case HCI_OP_READ_LOCAL_NAME:
1674 hci_cc_read_local_name(hdev, skb);
1675 break;
1676
1677 case HCI_OP_WRITE_AUTH_ENABLE:
1678 hci_cc_write_auth_enable(hdev, skb);
1679 break;
1680
1681 case HCI_OP_WRITE_ENCRYPT_MODE:
1682 hci_cc_write_encrypt_mode(hdev, skb);
1683 break;
1684
1685 case HCI_OP_WRITE_SCAN_ENABLE:
1686 hci_cc_write_scan_enable(hdev, skb);
1687 break;
1688
1689 case HCI_OP_READ_CLASS_OF_DEV:
1690 hci_cc_read_class_of_dev(hdev, skb);
1691 break;
1692
1693 case HCI_OP_WRITE_CLASS_OF_DEV:
1694 hci_cc_write_class_of_dev(hdev, skb);
1695 break;
1696
1697 case HCI_OP_READ_VOICE_SETTING:
1698 hci_cc_read_voice_setting(hdev, skb);
1699 break;
1700
1701 case HCI_OP_WRITE_VOICE_SETTING:
1702 hci_cc_write_voice_setting(hdev, skb);
1703 break;
1704
1705 case HCI_OP_HOST_BUFFER_SIZE:
1706 hci_cc_host_buffer_size(hdev, skb);
1707 break;
1708
Marcel Holtmann333140b2008-07-14 20:13:48 +02001709 case HCI_OP_READ_SSP_MODE:
1710 hci_cc_read_ssp_mode(hdev, skb);
1711 break;
1712
1713 case HCI_OP_WRITE_SSP_MODE:
1714 hci_cc_write_ssp_mode(hdev, skb);
1715 break;
1716
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001717 case HCI_OP_READ_LOCAL_VERSION:
1718 hci_cc_read_local_version(hdev, skb);
1719 break;
1720
1721 case HCI_OP_READ_LOCAL_COMMANDS:
1722 hci_cc_read_local_commands(hdev, skb);
1723 break;
1724
1725 case HCI_OP_READ_LOCAL_FEATURES:
1726 hci_cc_read_local_features(hdev, skb);
1727 break;
1728
1729 case HCI_OP_READ_BUFFER_SIZE:
1730 hci_cc_read_buffer_size(hdev, skb);
1731 break;
1732
1733 case HCI_OP_READ_BD_ADDR:
1734 hci_cc_read_bd_addr(hdev, skb);
1735 break;
1736
Johan Hedberg23bb5762010-12-21 23:01:27 +02001737 case HCI_OP_WRITE_CA_TIMEOUT:
1738 hci_cc_write_ca_timeout(hdev, skb);
1739 break;
1740
Johan Hedbergb0916ea2011-01-10 13:44:55 +02001741 case HCI_OP_DELETE_STORED_LINK_KEY:
1742 hci_cc_delete_stored_link_key(hdev, skb);
1743 break;
1744
Johan Hedbergd5859e22011-01-25 01:19:58 +02001745 case HCI_OP_SET_EVENT_MASK:
1746 hci_cc_set_event_mask(hdev, skb);
1747 break;
1748
1749 case HCI_OP_WRITE_INQUIRY_MODE:
1750 hci_cc_write_inquiry_mode(hdev, skb);
1751 break;
1752
1753 case HCI_OP_READ_INQ_RSP_TX_POWER:
1754 hci_cc_read_inq_rsp_tx_power(hdev, skb);
1755 break;
1756
1757 case HCI_OP_SET_EVENT_FLT:
1758 hci_cc_set_event_flt(hdev, skb);
1759 break;
1760
Johan Hedberg980e1a52011-01-22 06:10:07 +02001761 case HCI_OP_PIN_CODE_REPLY:
1762 hci_cc_pin_code_reply(hdev, skb);
1763 break;
1764
1765 case HCI_OP_PIN_CODE_NEG_REPLY:
1766 hci_cc_pin_code_neg_reply(hdev, skb);
1767 break;
1768
Szymon Jancc35938b2011-03-22 13:12:21 +01001769 case HCI_OP_READ_LOCAL_OOB_DATA:
1770 hci_cc_read_local_oob_data_reply(hdev, skb);
1771 break;
1772
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001773 case HCI_OP_LE_READ_BUFFER_SIZE:
1774 hci_cc_le_read_buffer_size(hdev, skb);
1775 break;
1776
Johan Hedberga5c29682011-02-19 12:05:57 -03001777 case HCI_OP_USER_CONFIRM_REPLY:
1778 hci_cc_user_confirm_reply(hdev, skb);
1779 break;
1780
1781 case HCI_OP_USER_CONFIRM_NEG_REPLY:
1782 hci_cc_user_confirm_neg_reply(hdev, skb);
1783 break;
1784
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001785 default:
1786 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1787 break;
1788 }
1789
Ville Tervo6bd32322011-02-16 16:32:41 +02001790 if (ev->opcode != HCI_OP_NOP)
1791 del_timer(&hdev->cmd_timer);
1792
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001793 if (ev->ncmd) {
1794 atomic_set(&hdev->cmd_cnt, 1);
1795 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001796 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001797 }
1798}
1799
1800static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1801{
1802 struct hci_ev_cmd_status *ev = (void *) skb->data;
1803 __u16 opcode;
1804
1805 skb_pull(skb, sizeof(*ev));
1806
1807 opcode = __le16_to_cpu(ev->opcode);
1808
1809 switch (opcode) {
1810 case HCI_OP_INQUIRY:
1811 hci_cs_inquiry(hdev, ev->status);
1812 break;
1813
1814 case HCI_OP_CREATE_CONN:
1815 hci_cs_create_conn(hdev, ev->status);
1816 break;
1817
1818 case HCI_OP_ADD_SCO:
1819 hci_cs_add_sco(hdev, ev->status);
1820 break;
1821
Marcel Holtmannf8558552008-07-14 20:13:49 +02001822 case HCI_OP_AUTH_REQUESTED:
1823 hci_cs_auth_requested(hdev, ev->status);
1824 break;
1825
1826 case HCI_OP_SET_CONN_ENCRYPT:
1827 hci_cs_set_conn_encrypt(hdev, ev->status);
1828 break;
1829
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001830 case HCI_OP_REMOTE_NAME_REQ:
1831 hci_cs_remote_name_req(hdev, ev->status);
1832 break;
1833
Marcel Holtmann769be972008-07-14 20:13:49 +02001834 case HCI_OP_READ_REMOTE_FEATURES:
1835 hci_cs_read_remote_features(hdev, ev->status);
1836 break;
1837
1838 case HCI_OP_READ_REMOTE_EXT_FEATURES:
1839 hci_cs_read_remote_ext_features(hdev, ev->status);
1840 break;
1841
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001842 case HCI_OP_SETUP_SYNC_CONN:
1843 hci_cs_setup_sync_conn(hdev, ev->status);
1844 break;
1845
1846 case HCI_OP_SNIFF_MODE:
1847 hci_cs_sniff_mode(hdev, ev->status);
1848 break;
1849
1850 case HCI_OP_EXIT_SNIFF_MODE:
1851 hci_cs_exit_sniff_mode(hdev, ev->status);
1852 break;
1853
Johan Hedberg8962ee72011-01-20 12:40:27 +02001854 case HCI_OP_DISCONNECT:
1855 if (ev->status != 0)
1856 mgmt_disconnect_failed(hdev->id);
1857 break;
1858
Ville Tervofcd89c02011-02-10 22:38:47 -03001859 case HCI_OP_LE_CREATE_CONN:
1860 hci_cs_le_create_conn(hdev, ev->status);
1861 break;
1862
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001863 default:
1864 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1865 break;
1866 }
1867
Ville Tervo6bd32322011-02-16 16:32:41 +02001868 if (ev->opcode != HCI_OP_NOP)
1869 del_timer(&hdev->cmd_timer);
1870
Gustavo F. Padovan10572132011-03-16 15:36:29 -03001871 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001872 atomic_set(&hdev->cmd_cnt, 1);
1873 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001874 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001875 }
1876}
1877
1878static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1879{
1880 struct hci_ev_role_change *ev = (void *) skb->data;
1881 struct hci_conn *conn;
1882
1883 BT_DBG("%s status %d", hdev->name, ev->status);
1884
1885 hci_dev_lock(hdev);
1886
1887 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1888 if (conn) {
1889 if (!ev->status) {
1890 if (ev->role)
1891 conn->link_mode &= ~HCI_LM_MASTER;
1892 else
1893 conn->link_mode |= HCI_LM_MASTER;
1894 }
1895
1896 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1897
1898 hci_role_switch_cfm(conn, ev->status, ev->role);
1899 }
1900
1901 hci_dev_unlock(hdev);
1902}
1903
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
1905{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001906 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001907 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 int i;
1909
1910 skb_pull(skb, sizeof(*ev));
1911
1912 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
1913
1914 if (skb->len < ev->num_hndl * 4) {
1915 BT_DBG("%s bad parameters", hdev->name);
1916 return;
1917 }
1918
1919 tasklet_disable(&hdev->tx_task);
1920
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001921 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 struct hci_conn *conn;
1923 __u16 handle, count;
1924
Harvey Harrison83985312008-05-02 16:25:46 -07001925 handle = get_unaligned_le16(ptr++);
1926 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927
1928 conn = hci_conn_hash_lookup_handle(hdev, handle);
1929 if (conn) {
1930 conn->sent -= count;
1931
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001932 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001933 hdev->acl_cnt += count;
1934 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935 hdev->acl_cnt = hdev->acl_pkts;
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001936 } else if (conn->type == LE_LINK) {
1937 if (hdev->le_pkts) {
1938 hdev->le_cnt += count;
1939 if (hdev->le_cnt > hdev->le_pkts)
1940 hdev->le_cnt = hdev->le_pkts;
1941 } else {
1942 hdev->acl_cnt += count;
1943 if (hdev->acl_cnt > hdev->acl_pkts)
1944 hdev->acl_cnt = hdev->acl_pkts;
1945 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001946 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001947 hdev->sco_cnt += count;
1948 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001949 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 }
1951 }
1952 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001953
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001954 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955
1956 tasklet_enable(&hdev->tx_task);
1957}
1958
Marcel Holtmann04837f62006-07-03 10:02:33 +02001959static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001961 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001962 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963
1964 BT_DBG("%s status %d", hdev->name, ev->status);
1965
1966 hci_dev_lock(hdev);
1967
Marcel Holtmann04837f62006-07-03 10:02:33 +02001968 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1969 if (conn) {
1970 conn->mode = ev->mode;
1971 conn->interval = __le16_to_cpu(ev->interval);
1972
1973 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
1974 if (conn->mode == HCI_CM_ACTIVE)
1975 conn->power_save = 1;
1976 else
1977 conn->power_save = 0;
1978 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001979
1980 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1981 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001982 }
1983
1984 hci_dev_unlock(hdev);
1985}
1986
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1988{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001989 struct hci_ev_pin_code_req *ev = (void *) skb->data;
1990 struct hci_conn *conn;
1991
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001992 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001993
1994 hci_dev_lock(hdev);
1995
1996 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Marcel Holtmann3d7a9d12009-05-09 12:09:21 -07001997 if (conn && conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001998 hci_conn_hold(conn);
1999 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2000 hci_conn_put(conn);
2001 }
2002
Johan Hedberg03b555e2011-01-04 15:40:05 +02002003 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
2004 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2005 sizeof(ev->bdaddr), &ev->bdaddr);
2006
Johan Hedberg980e1a52011-01-22 06:10:07 +02002007 if (test_bit(HCI_MGMT, &hdev->flags))
2008 mgmt_pin_code_request(hdev->id, &ev->bdaddr);
2009
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002010 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011}
2012
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2014{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002015 struct hci_ev_link_key_req *ev = (void *) skb->data;
2016 struct hci_cp_link_key_reply cp;
2017 struct hci_conn *conn;
2018 struct link_key *key;
2019
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002020 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002021
2022 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
2023 return;
2024
2025 hci_dev_lock(hdev);
2026
2027 key = hci_find_link_key(hdev, &ev->bdaddr);
2028 if (!key) {
2029 BT_DBG("%s link key not found for %s", hdev->name,
2030 batostr(&ev->bdaddr));
2031 goto not_found;
2032 }
2033
2034 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2035 batostr(&ev->bdaddr));
2036
2037 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) {
2038 BT_DBG("%s ignoring debug key", hdev->name);
2039 goto not_found;
2040 }
2041
2042 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2043
2044 if (key->type == 0x04 && conn && conn->auth_type != 0xff &&
2045 (conn->auth_type & 0x01)) {
2046 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2047 goto not_found;
2048 }
2049
2050 bacpy(&cp.bdaddr, &ev->bdaddr);
2051 memcpy(cp.link_key, key->val, 16);
2052
2053 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2054
2055 hci_dev_unlock(hdev);
2056
2057 return;
2058
2059not_found:
2060 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2061 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062}
2063
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2065{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002066 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2067 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002068 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002069
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002070 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002071
2072 hci_dev_lock(hdev);
2073
2074 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2075 if (conn) {
2076 hci_conn_hold(conn);
2077 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002078 pin_len = conn->pin_length;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002079 hci_conn_put(conn);
2080 }
2081
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002082 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
2083 hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key,
2084 ev->key_type, pin_len);
2085
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002086 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087}
2088
Marcel Holtmann04837f62006-07-03 10:02:33 +02002089static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2090{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002091 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002092 struct hci_conn *conn;
2093
2094 BT_DBG("%s status %d", hdev->name, ev->status);
2095
2096 hci_dev_lock(hdev);
2097
2098 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099 if (conn && !ev->status) {
2100 struct inquiry_entry *ie;
2101
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002102 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2103 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002104 ie->data.clock_offset = ev->clock_offset;
2105 ie->timestamp = jiffies;
2106 }
2107 }
2108
2109 hci_dev_unlock(hdev);
2110}
2111
Marcel Holtmanna8746412008-07-14 20:13:46 +02002112static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2113{
2114 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2115 struct hci_conn *conn;
2116
2117 BT_DBG("%s status %d", hdev->name, ev->status);
2118
2119 hci_dev_lock(hdev);
2120
2121 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2122 if (conn && !ev->status)
2123 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2124
2125 hci_dev_unlock(hdev);
2126}
2127
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002128static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2129{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002130 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002131 struct inquiry_entry *ie;
2132
2133 BT_DBG("%s", hdev->name);
2134
2135 hci_dev_lock(hdev);
2136
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002137 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2138 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002139 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2140 ie->timestamp = jiffies;
2141 }
2142
2143 hci_dev_unlock(hdev);
2144}
2145
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002146static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2147{
2148 struct inquiry_data data;
2149 int num_rsp = *((__u8 *) skb->data);
2150
2151 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2152
2153 if (!num_rsp)
2154 return;
2155
2156 hci_dev_lock(hdev);
2157
2158 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002159 struct inquiry_info_with_rssi_and_pscan_mode *info;
2160 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002161
Johan Hedberge17acd42011-03-30 23:57:16 +03002162 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002163 bacpy(&data.bdaddr, &info->bdaddr);
2164 data.pscan_rep_mode = info->pscan_rep_mode;
2165 data.pscan_period_mode = info->pscan_period_mode;
2166 data.pscan_mode = info->pscan_mode;
2167 memcpy(data.dev_class, info->dev_class, 3);
2168 data.clock_offset = info->clock_offset;
2169 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002170 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002171 hci_inquiry_cache_update(hdev, &data);
Johan Hedberge17acd42011-03-30 23:57:16 +03002172 mgmt_device_found(hdev->id, &info->bdaddr,
2173 info->dev_class, info->rssi,
2174 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002175 }
2176 } else {
2177 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2178
Johan Hedberge17acd42011-03-30 23:57:16 +03002179 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002180 bacpy(&data.bdaddr, &info->bdaddr);
2181 data.pscan_rep_mode = info->pscan_rep_mode;
2182 data.pscan_period_mode = info->pscan_period_mode;
2183 data.pscan_mode = 0x00;
2184 memcpy(data.dev_class, info->dev_class, 3);
2185 data.clock_offset = info->clock_offset;
2186 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002187 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002188 hci_inquiry_cache_update(hdev, &data);
Johan Hedberge17acd42011-03-30 23:57:16 +03002189 mgmt_device_found(hdev->id, &info->bdaddr,
2190 info->dev_class, info->rssi,
2191 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002192 }
2193 }
2194
2195 hci_dev_unlock(hdev);
2196}
2197
2198static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2199{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002200 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2201 struct hci_conn *conn;
2202
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002203 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002204
Marcel Holtmann41a96212008-07-14 20:13:48 +02002205 hci_dev_lock(hdev);
2206
2207 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002208 if (!conn)
2209 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002210
Johan Hedbergccd556f2010-11-10 17:11:51 +02002211 if (!ev->status && ev->page == 0x01) {
2212 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002213
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002214 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2215 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002216 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002217
Johan Hedbergccd556f2010-11-10 17:11:51 +02002218 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002219 }
2220
Johan Hedbergccd556f2010-11-10 17:11:51 +02002221 if (conn->state != BT_CONFIG)
2222 goto unlock;
2223
Johan Hedberg127178d2010-11-18 22:22:29 +02002224 if (!ev->status) {
2225 struct hci_cp_remote_name_req cp;
2226 memset(&cp, 0, sizeof(cp));
2227 bacpy(&cp.bdaddr, &conn->dst);
2228 cp.pscan_rep_mode = 0x02;
2229 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2230 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002231
Johan Hedberg127178d2010-11-18 22:22:29 +02002232 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002233 conn->state = BT_CONNECTED;
2234 hci_proto_connect_cfm(conn, ev->status);
2235 hci_conn_put(conn);
2236 }
2237
2238unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002239 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002240}
2241
2242static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2243{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002244 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2245 struct hci_conn *conn;
2246
2247 BT_DBG("%s status %d", hdev->name, ev->status);
2248
2249 hci_dev_lock(hdev);
2250
2251 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002252 if (!conn) {
2253 if (ev->link_type == ESCO_LINK)
2254 goto unlock;
2255
2256 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2257 if (!conn)
2258 goto unlock;
2259
2260 conn->type = SCO_LINK;
2261 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002262
Marcel Holtmann732547f2009-04-19 19:14:14 +02002263 switch (ev->status) {
2264 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002265 conn->handle = __le16_to_cpu(ev->handle);
2266 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002267
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002268 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002269 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002270 break;
2271
Stephen Coe705e5712010-02-16 11:29:44 -05002272 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002273 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002274 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002275 case 0x1f: /* Unspecified error */
2276 if (conn->out && conn->attempt < 2) {
2277 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2278 (hdev->esco_type & EDR_ESCO_MASK);
2279 hci_setup_sync(conn, conn->link->handle);
2280 goto unlock;
2281 }
2282 /* fall through */
2283
2284 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002285 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002286 break;
2287 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002288
2289 hci_proto_connect_cfm(conn, ev->status);
2290 if (ev->status)
2291 hci_conn_del(conn);
2292
2293unlock:
2294 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002295}
2296
2297static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2298{
2299 BT_DBG("%s", hdev->name);
2300}
2301
Marcel Holtmann04837f62006-07-03 10:02:33 +02002302static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2303{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002304 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002305
2306 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002307}
2308
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002309static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2310{
2311 struct inquiry_data data;
2312 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2313 int num_rsp = *((__u8 *) skb->data);
2314
2315 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2316
2317 if (!num_rsp)
2318 return;
2319
2320 hci_dev_lock(hdev);
2321
Johan Hedberge17acd42011-03-30 23:57:16 +03002322 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002323 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002324 data.pscan_rep_mode = info->pscan_rep_mode;
2325 data.pscan_period_mode = info->pscan_period_mode;
2326 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002327 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002328 data.clock_offset = info->clock_offset;
2329 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002330 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002331 hci_inquiry_cache_update(hdev, &data);
Johan Hedberge17acd42011-03-30 23:57:16 +03002332 mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class,
2333 info->rssi, info->data);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002334 }
2335
2336 hci_dev_unlock(hdev);
2337}
2338
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002339static inline u8 hci_get_auth_req(struct hci_conn *conn)
2340{
2341 /* If remote requests dedicated bonding follow that lead */
2342 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2343 /* If both remote and local IO capabilities allow MITM
2344 * protection then require it, otherwise don't */
2345 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2346 return 0x02;
2347 else
2348 return 0x03;
2349 }
2350
2351 /* If remote requests no-bonding follow that lead */
2352 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
2353 return 0x00;
2354
2355 return conn->auth_type;
2356}
2357
Marcel Holtmann04936842008-07-14 20:13:48 +02002358static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2359{
2360 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2361 struct hci_conn *conn;
2362
2363 BT_DBG("%s", hdev->name);
2364
2365 hci_dev_lock(hdev);
2366
2367 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002368 if (!conn)
2369 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002370
Johan Hedberg03b555e2011-01-04 15:40:05 +02002371 hci_conn_hold(conn);
2372
2373 if (!test_bit(HCI_MGMT, &hdev->flags))
2374 goto unlock;
2375
2376 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
2377 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002378 struct hci_cp_io_capability_reply cp;
2379
2380 bacpy(&cp.bdaddr, &ev->bdaddr);
2381 cp.capability = conn->io_capability;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002382 cp.authentication = hci_get_auth_req(conn);
2383
Szymon Jancce85ee12011-03-22 13:12:23 +01002384 if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
2385 hci_find_remote_oob_data(hdev, &conn->dst))
2386 cp.oob_data = 0x01;
2387 else
2388 cp.oob_data = 0x00;
2389
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002390 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2391 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002392 } else {
2393 struct hci_cp_io_capability_neg_reply cp;
2394
2395 bacpy(&cp.bdaddr, &ev->bdaddr);
2396 cp.reason = 0x16; /* Pairing not allowed */
2397
2398 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2399 sizeof(cp), &cp);
2400 }
2401
2402unlock:
2403 hci_dev_unlock(hdev);
2404}
2405
2406static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2407{
2408 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2409 struct hci_conn *conn;
2410
2411 BT_DBG("%s", hdev->name);
2412
2413 hci_dev_lock(hdev);
2414
2415 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2416 if (!conn)
2417 goto unlock;
2418
2419 hci_conn_hold(conn);
2420
2421 conn->remote_cap = ev->capability;
2422 conn->remote_oob = ev->oob_data;
2423 conn->remote_auth = ev->authentication;
2424
2425unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002426 hci_dev_unlock(hdev);
2427}
2428
Johan Hedberga5c29682011-02-19 12:05:57 -03002429static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2430 struct sk_buff *skb)
2431{
2432 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
2433
2434 BT_DBG("%s", hdev->name);
2435
2436 hci_dev_lock(hdev);
2437
2438 if (test_bit(HCI_MGMT, &hdev->flags))
2439 mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
2440
2441 hci_dev_unlock(hdev);
2442}
2443
Marcel Holtmann04936842008-07-14 20:13:48 +02002444static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2445{
2446 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
2447 struct hci_conn *conn;
2448
2449 BT_DBG("%s", hdev->name);
2450
2451 hci_dev_lock(hdev);
2452
2453 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03002454 if (!conn)
2455 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002456
Johan Hedberg2a611692011-02-19 12:06:00 -03002457 /* To avoid duplicate auth_failed events to user space we check
2458 * the HCI_CONN_AUTH_PEND flag which will be set if we
2459 * initiated the authentication. A traditional auth_complete
2460 * event gets always produced as initiator and is also mapped to
2461 * the mgmt_auth_failed event */
2462 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
2463 mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
2464
2465 hci_conn_put(conn);
2466
2467unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002468 hci_dev_unlock(hdev);
2469}
2470
Marcel Holtmann41a96212008-07-14 20:13:48 +02002471static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2472{
2473 struct hci_ev_remote_host_features *ev = (void *) skb->data;
2474 struct inquiry_entry *ie;
2475
2476 BT_DBG("%s", hdev->name);
2477
2478 hci_dev_lock(hdev);
2479
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002480 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2481 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02002482 ie->data.ssp_mode = (ev->features[0] & 0x01);
2483
2484 hci_dev_unlock(hdev);
2485}
2486
Szymon Janc2763eda2011-03-22 13:12:22 +01002487static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
2488 struct sk_buff *skb)
2489{
2490 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
2491 struct oob_data *data;
2492
2493 BT_DBG("%s", hdev->name);
2494
2495 hci_dev_lock(hdev);
2496
2497 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
2498 if (data) {
2499 struct hci_cp_remote_oob_data_reply cp;
2500
2501 bacpy(&cp.bdaddr, &ev->bdaddr);
2502 memcpy(cp.hash, data->hash, sizeof(cp.hash));
2503 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
2504
2505 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
2506 &cp);
2507 } else {
2508 struct hci_cp_remote_oob_data_neg_reply cp;
2509
2510 bacpy(&cp.bdaddr, &ev->bdaddr);
2511 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
2512 &cp);
2513 }
2514
2515 hci_dev_unlock(hdev);
2516}
2517
Ville Tervofcd89c02011-02-10 22:38:47 -03002518static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2519{
2520 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2521 struct hci_conn *conn;
2522
2523 BT_DBG("%s status %d", hdev->name, ev->status);
2524
2525 hci_dev_lock(hdev);
2526
2527 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03002528 if (!conn) {
2529 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
2530 if (!conn) {
2531 BT_ERR("No memory for new connection");
2532 hci_dev_unlock(hdev);
2533 return;
2534 }
2535 }
Ville Tervofcd89c02011-02-10 22:38:47 -03002536
2537 if (ev->status) {
2538 hci_proto_connect_cfm(conn, ev->status);
2539 conn->state = BT_CLOSED;
2540 hci_conn_del(conn);
2541 goto unlock;
2542 }
2543
2544 conn->handle = __le16_to_cpu(ev->handle);
2545 conn->state = BT_CONNECTED;
2546
2547 hci_conn_hold_device(conn);
2548 hci_conn_add_sysfs(conn);
2549
2550 hci_proto_connect_cfm(conn, ev->status);
2551
2552unlock:
2553 hci_dev_unlock(hdev);
2554}
2555
2556static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
2557{
2558 struct hci_ev_le_meta *le_ev = (void *) skb->data;
2559
2560 skb_pull(skb, sizeof(*le_ev));
2561
2562 switch (le_ev->subevent) {
2563 case HCI_EV_LE_CONN_COMPLETE:
2564 hci_le_conn_complete_evt(hdev, skb);
2565 break;
2566
2567 default:
2568 break;
2569 }
2570}
2571
Linus Torvalds1da177e2005-04-16 15:20:36 -07002572void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
2573{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002574 struct hci_event_hdr *hdr = (void *) skb->data;
2575 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576
2577 skb_pull(skb, HCI_EVENT_HDR_SIZE);
2578
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002579 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580 case HCI_EV_INQUIRY_COMPLETE:
2581 hci_inquiry_complete_evt(hdev, skb);
2582 break;
2583
2584 case HCI_EV_INQUIRY_RESULT:
2585 hci_inquiry_result_evt(hdev, skb);
2586 break;
2587
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002588 case HCI_EV_CONN_COMPLETE:
2589 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02002590 break;
2591
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592 case HCI_EV_CONN_REQUEST:
2593 hci_conn_request_evt(hdev, skb);
2594 break;
2595
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596 case HCI_EV_DISCONN_COMPLETE:
2597 hci_disconn_complete_evt(hdev, skb);
2598 break;
2599
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 case HCI_EV_AUTH_COMPLETE:
2601 hci_auth_complete_evt(hdev, skb);
2602 break;
2603
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002604 case HCI_EV_REMOTE_NAME:
2605 hci_remote_name_evt(hdev, skb);
2606 break;
2607
Linus Torvalds1da177e2005-04-16 15:20:36 -07002608 case HCI_EV_ENCRYPT_CHANGE:
2609 hci_encrypt_change_evt(hdev, skb);
2610 break;
2611
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002612 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
2613 hci_change_link_key_complete_evt(hdev, skb);
2614 break;
2615
2616 case HCI_EV_REMOTE_FEATURES:
2617 hci_remote_features_evt(hdev, skb);
2618 break;
2619
2620 case HCI_EV_REMOTE_VERSION:
2621 hci_remote_version_evt(hdev, skb);
2622 break;
2623
2624 case HCI_EV_QOS_SETUP_COMPLETE:
2625 hci_qos_setup_complete_evt(hdev, skb);
2626 break;
2627
2628 case HCI_EV_CMD_COMPLETE:
2629 hci_cmd_complete_evt(hdev, skb);
2630 break;
2631
2632 case HCI_EV_CMD_STATUS:
2633 hci_cmd_status_evt(hdev, skb);
2634 break;
2635
2636 case HCI_EV_ROLE_CHANGE:
2637 hci_role_change_evt(hdev, skb);
2638 break;
2639
2640 case HCI_EV_NUM_COMP_PKTS:
2641 hci_num_comp_pkts_evt(hdev, skb);
2642 break;
2643
2644 case HCI_EV_MODE_CHANGE:
2645 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646 break;
2647
2648 case HCI_EV_PIN_CODE_REQ:
2649 hci_pin_code_request_evt(hdev, skb);
2650 break;
2651
2652 case HCI_EV_LINK_KEY_REQ:
2653 hci_link_key_request_evt(hdev, skb);
2654 break;
2655
2656 case HCI_EV_LINK_KEY_NOTIFY:
2657 hci_link_key_notify_evt(hdev, skb);
2658 break;
2659
2660 case HCI_EV_CLOCK_OFFSET:
2661 hci_clock_offset_evt(hdev, skb);
2662 break;
2663
Marcel Holtmanna8746412008-07-14 20:13:46 +02002664 case HCI_EV_PKT_TYPE_CHANGE:
2665 hci_pkt_type_change_evt(hdev, skb);
2666 break;
2667
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002668 case HCI_EV_PSCAN_REP_MODE:
2669 hci_pscan_rep_mode_evt(hdev, skb);
2670 break;
2671
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002672 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
2673 hci_inquiry_result_with_rssi_evt(hdev, skb);
2674 break;
2675
2676 case HCI_EV_REMOTE_EXT_FEATURES:
2677 hci_remote_ext_features_evt(hdev, skb);
2678 break;
2679
2680 case HCI_EV_SYNC_CONN_COMPLETE:
2681 hci_sync_conn_complete_evt(hdev, skb);
2682 break;
2683
2684 case HCI_EV_SYNC_CONN_CHANGED:
2685 hci_sync_conn_changed_evt(hdev, skb);
2686 break;
2687
Marcel Holtmann04837f62006-07-03 10:02:33 +02002688 case HCI_EV_SNIFF_SUBRATE:
2689 hci_sniff_subrate_evt(hdev, skb);
2690 break;
2691
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002692 case HCI_EV_EXTENDED_INQUIRY_RESULT:
2693 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002694 break;
2695
Marcel Holtmann04936842008-07-14 20:13:48 +02002696 case HCI_EV_IO_CAPA_REQUEST:
2697 hci_io_capa_request_evt(hdev, skb);
2698 break;
2699
Johan Hedberg03b555e2011-01-04 15:40:05 +02002700 case HCI_EV_IO_CAPA_REPLY:
2701 hci_io_capa_reply_evt(hdev, skb);
2702 break;
2703
Johan Hedberga5c29682011-02-19 12:05:57 -03002704 case HCI_EV_USER_CONFIRM_REQUEST:
2705 hci_user_confirm_request_evt(hdev, skb);
2706 break;
2707
Marcel Holtmann04936842008-07-14 20:13:48 +02002708 case HCI_EV_SIMPLE_PAIR_COMPLETE:
2709 hci_simple_pair_complete_evt(hdev, skb);
2710 break;
2711
Marcel Holtmann41a96212008-07-14 20:13:48 +02002712 case HCI_EV_REMOTE_HOST_FEATURES:
2713 hci_remote_host_features_evt(hdev, skb);
2714 break;
2715
Ville Tervofcd89c02011-02-10 22:38:47 -03002716 case HCI_EV_LE_META:
2717 hci_le_meta_evt(hdev, skb);
2718 break;
2719
Szymon Janc2763eda2011-03-22 13:12:22 +01002720 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
2721 hci_remote_oob_data_request_evt(hdev, skb);
2722 break;
2723
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002724 default:
2725 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002726 break;
2727 }
2728
2729 kfree_skb(skb);
2730 hdev->stat.evt_rx++;
2731}
2732
2733/* Generate internal stack event */
2734void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
2735{
2736 struct hci_event_hdr *hdr;
2737 struct hci_ev_stack_internal *ev;
2738 struct sk_buff *skb;
2739
2740 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
2741 if (!skb)
2742 return;
2743
2744 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
2745 hdr->evt = HCI_EV_STACK_INTERNAL;
2746 hdr->plen = sizeof(*ev) + dlen;
2747
2748 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
2749 ev->type = type;
2750 memcpy(ev->data, data, dlen);
2751
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002752 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07002753 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002754
Marcel Holtmann0d48d932005-08-09 20:30:28 -07002755 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02002757 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002758 kfree_skb(skb);
2759}