blob: 833797e9654b121ba535ddc4bdea3f36110e0ae5 [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
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 for (; num_rsp; num_rsp--) {
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 info++;
1241 hci_inquiry_cache_update(hdev, &data);
1242 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001243
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244 hci_dev_unlock(hdev);
1245}
1246
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001247static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001249 struct hci_ev_conn_complete *ev = (void *) skb->data;
1250 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001252 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001253
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001255
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001256 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001257 if (!conn) {
1258 if (ev->link_type != SCO_LINK)
1259 goto unlock;
1260
1261 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1262 if (!conn)
1263 goto unlock;
1264
1265 conn->type = SCO_LINK;
1266 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001267
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001268 if (!ev->status) {
1269 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001270
1271 if (conn->type == ACL_LINK) {
1272 conn->state = BT_CONFIG;
1273 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001274 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedbergf7520542011-01-20 12:34:39 +02001275 mgmt_connected(hdev->id, &ev->bdaddr);
Marcel Holtmann769be972008-07-14 20:13:49 +02001276 } else
1277 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001278
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001279 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001280 hci_conn_add_sysfs(conn);
1281
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001282 if (test_bit(HCI_AUTH, &hdev->flags))
1283 conn->link_mode |= HCI_LM_AUTH;
1284
1285 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1286 conn->link_mode |= HCI_LM_ENCRYPT;
1287
1288 /* Get remote features */
1289 if (conn->type == ACL_LINK) {
1290 struct hci_cp_read_remote_features cp;
1291 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001292 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1293 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001294 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001295
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001296 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +02001297 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001298 struct hci_cp_change_conn_ptype cp;
1299 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001300 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1301 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1302 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001303 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001304 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001305 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001306 if (conn->type == ACL_LINK)
1307 mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status);
1308 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001309
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001310 if (conn->type == ACL_LINK)
1311 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001312
Marcel Holtmann769be972008-07-14 20:13:49 +02001313 if (ev->status) {
1314 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001315 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001316 } else if (ev->link_type != ACL_LINK)
1317 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001318
1319unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001321
1322 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323}
1324
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1326{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001327 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 int mask = hdev->link_mode;
1329
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001330 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1331 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332
1333 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1334
Szymon Janc138d22e2011-02-17 16:44:23 +01001335 if ((mask & HCI_LM_ACCEPT) &&
1336 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001338 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340
1341 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001342
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001343 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1344 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001345 memcpy(ie->data.dev_class, ev->dev_class, 3);
1346
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1348 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001349 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1350 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001351 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 hci_dev_unlock(hdev);
1353 return;
1354 }
1355 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001356
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357 memcpy(conn->dev_class, ev->dev_class, 3);
1358 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001359
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360 hci_dev_unlock(hdev);
1361
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001362 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1363 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001365 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001367 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1368 cp.role = 0x00; /* Become master */
1369 else
1370 cp.role = 0x01; /* Remain slave */
1371
1372 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1373 sizeof(cp), &cp);
1374 } else {
1375 struct hci_cp_accept_sync_conn_req cp;
1376
1377 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001378 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001379
1380 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1381 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1382 cp.max_latency = cpu_to_le16(0xffff);
1383 cp.content_format = cpu_to_le16(hdev->voice_setting);
1384 cp.retrans_effort = 0xff;
1385
1386 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1387 sizeof(cp), &cp);
1388 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389 } else {
1390 /* Connection rejected */
1391 struct hci_cp_reject_conn_req cp;
1392
1393 bacpy(&cp.bdaddr, &ev->bdaddr);
1394 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001395 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 }
1397}
1398
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1400{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001401 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001402 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403
1404 BT_DBG("%s status %d", hdev->name, ev->status);
1405
Johan Hedberg8962ee72011-01-20 12:40:27 +02001406 if (ev->status) {
1407 mgmt_disconnect_failed(hdev->id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 return;
Johan Hedberg8962ee72011-01-20 12:40:27 +02001409 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410
1411 hci_dev_lock(hdev);
1412
Marcel Holtmann04837f62006-07-03 10:02:33 +02001413 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001414 if (!conn)
1415 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001416
Johan Hedbergf7520542011-01-20 12:34:39 +02001417 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418
Johan Hedbergf7520542011-01-20 12:34:39 +02001419 if (conn->type == ACL_LINK)
1420 mgmt_disconnected(hdev->id, &conn->dst);
1421
1422 hci_proto_disconn_cfm(conn, ev->reason);
1423 hci_conn_del(conn);
1424
1425unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426 hci_dev_unlock(hdev);
1427}
1428
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001429static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1430{
1431 struct hci_ev_auth_complete *ev = (void *) skb->data;
1432 struct hci_conn *conn;
1433
1434 BT_DBG("%s status %d", hdev->name, ev->status);
1435
1436 hci_dev_lock(hdev);
1437
1438 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1439 if (conn) {
Johan Hedberg765c2a92011-01-19 12:06:52 +05301440 if (!ev->status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001441 conn->link_mode |= HCI_LM_AUTH;
Johan Hedberg765c2a92011-01-19 12:06:52 +05301442 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001443 } else {
1444 mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
Johan Hedbergda213f42010-06-18 11:08:56 +03001445 conn->sec_level = BT_SECURITY_LOW;
Johan Hedberg2a611692011-02-19 12:06:00 -03001446 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001447
1448 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1449
Marcel Holtmannf8558552008-07-14 20:13:49 +02001450 if (conn->state == BT_CONFIG) {
1451 if (!ev->status && hdev->ssp_mode > 0 &&
1452 conn->ssp_mode > 0) {
1453 struct hci_cp_set_conn_encrypt cp;
1454 cp.handle = ev->handle;
1455 cp.encrypt = 0x01;
1456 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1457 sizeof(cp), &cp);
1458 } else {
1459 conn->state = BT_CONNECTED;
1460 hci_proto_connect_cfm(conn, ev->status);
1461 hci_conn_put(conn);
1462 }
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001463 } else {
Marcel Holtmannf8558552008-07-14 20:13:49 +02001464 hci_auth_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001465
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001466 hci_conn_hold(conn);
1467 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1468 hci_conn_put(conn);
1469 }
1470
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001471 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1472 if (!ev->status) {
1473 struct hci_cp_set_conn_encrypt cp;
Marcel Holtmannf8558552008-07-14 20:13:49 +02001474 cp.handle = ev->handle;
1475 cp.encrypt = 0x01;
1476 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1477 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001478 } else {
1479 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1480 hci_encrypt_cfm(conn, ev->status, 0x00);
1481 }
1482 }
1483 }
1484
1485 hci_dev_unlock(hdev);
1486}
1487
1488static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1489{
Johan Hedberg127178d2010-11-18 22:22:29 +02001490 struct hci_ev_remote_name *ev = (void *) skb->data;
1491 struct hci_conn *conn;
1492
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001493 BT_DBG("%s", hdev->name);
1494
1495 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001496
1497 hci_dev_lock(hdev);
1498
1499 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1500 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1501 struct hci_cp_auth_requested cp;
1502 cp.handle = __cpu_to_le16(conn->handle);
1503 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1504 }
1505
1506 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001507}
1508
1509static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1510{
1511 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1512 struct hci_conn *conn;
1513
1514 BT_DBG("%s status %d", hdev->name, ev->status);
1515
1516 hci_dev_lock(hdev);
1517
1518 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1519 if (conn) {
1520 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001521 if (ev->encrypt) {
1522 /* Encryption implies authentication */
1523 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001524 conn->link_mode |= HCI_LM_ENCRYPT;
Marcel Holtmannae293192008-07-14 20:13:45 +02001525 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001526 conn->link_mode &= ~HCI_LM_ENCRYPT;
1527 }
1528
1529 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1530
Marcel Holtmannf8558552008-07-14 20:13:49 +02001531 if (conn->state == BT_CONFIG) {
1532 if (!ev->status)
1533 conn->state = BT_CONNECTED;
1534
1535 hci_proto_connect_cfm(conn, ev->status);
1536 hci_conn_put(conn);
1537 } else
1538 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001539 }
1540
1541 hci_dev_unlock(hdev);
1542}
1543
1544static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1545{
1546 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1547 struct hci_conn *conn;
1548
1549 BT_DBG("%s status %d", hdev->name, ev->status);
1550
1551 hci_dev_lock(hdev);
1552
1553 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1554 if (conn) {
1555 if (!ev->status)
1556 conn->link_mode |= HCI_LM_SECURE;
1557
1558 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1559
1560 hci_key_change_cfm(conn, ev->status);
1561 }
1562
1563 hci_dev_unlock(hdev);
1564}
1565
1566static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1567{
1568 struct hci_ev_remote_features *ev = (void *) skb->data;
1569 struct hci_conn *conn;
1570
1571 BT_DBG("%s status %d", hdev->name, ev->status);
1572
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001573 hci_dev_lock(hdev);
1574
1575 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001576 if (!conn)
1577 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001578
Johan Hedbergccd556f2010-11-10 17:11:51 +02001579 if (!ev->status)
1580 memcpy(conn->features, ev->features, 8);
1581
1582 if (conn->state != BT_CONFIG)
1583 goto unlock;
1584
1585 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1586 struct hci_cp_read_remote_ext_features cp;
1587 cp.handle = ev->handle;
1588 cp.page = 0x01;
1589 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001590 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001591 goto unlock;
1592 }
1593
Johan Hedberg127178d2010-11-18 22:22:29 +02001594 if (!ev->status) {
1595 struct hci_cp_remote_name_req cp;
1596 memset(&cp, 0, sizeof(cp));
1597 bacpy(&cp.bdaddr, &conn->dst);
1598 cp.pscan_rep_mode = 0x02;
1599 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1600 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001601
Johan Hedberg127178d2010-11-18 22:22:29 +02001602 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001603 conn->state = BT_CONNECTED;
1604 hci_proto_connect_cfm(conn, ev->status);
1605 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001606 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001607
Johan Hedbergccd556f2010-11-10 17:11:51 +02001608unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001609 hci_dev_unlock(hdev);
1610}
1611
1612static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1613{
1614 BT_DBG("%s", hdev->name);
1615}
1616
1617static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1618{
1619 BT_DBG("%s", hdev->name);
1620}
1621
1622static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1623{
1624 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1625 __u16 opcode;
1626
1627 skb_pull(skb, sizeof(*ev));
1628
1629 opcode = __le16_to_cpu(ev->opcode);
1630
1631 switch (opcode) {
1632 case HCI_OP_INQUIRY_CANCEL:
1633 hci_cc_inquiry_cancel(hdev, skb);
1634 break;
1635
1636 case HCI_OP_EXIT_PERIODIC_INQ:
1637 hci_cc_exit_periodic_inq(hdev, skb);
1638 break;
1639
1640 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1641 hci_cc_remote_name_req_cancel(hdev, skb);
1642 break;
1643
1644 case HCI_OP_ROLE_DISCOVERY:
1645 hci_cc_role_discovery(hdev, skb);
1646 break;
1647
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001648 case HCI_OP_READ_LINK_POLICY:
1649 hci_cc_read_link_policy(hdev, skb);
1650 break;
1651
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001652 case HCI_OP_WRITE_LINK_POLICY:
1653 hci_cc_write_link_policy(hdev, skb);
1654 break;
1655
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001656 case HCI_OP_READ_DEF_LINK_POLICY:
1657 hci_cc_read_def_link_policy(hdev, skb);
1658 break;
1659
1660 case HCI_OP_WRITE_DEF_LINK_POLICY:
1661 hci_cc_write_def_link_policy(hdev, skb);
1662 break;
1663
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001664 case HCI_OP_RESET:
1665 hci_cc_reset(hdev, skb);
1666 break;
1667
1668 case HCI_OP_WRITE_LOCAL_NAME:
1669 hci_cc_write_local_name(hdev, skb);
1670 break;
1671
1672 case HCI_OP_READ_LOCAL_NAME:
1673 hci_cc_read_local_name(hdev, skb);
1674 break;
1675
1676 case HCI_OP_WRITE_AUTH_ENABLE:
1677 hci_cc_write_auth_enable(hdev, skb);
1678 break;
1679
1680 case HCI_OP_WRITE_ENCRYPT_MODE:
1681 hci_cc_write_encrypt_mode(hdev, skb);
1682 break;
1683
1684 case HCI_OP_WRITE_SCAN_ENABLE:
1685 hci_cc_write_scan_enable(hdev, skb);
1686 break;
1687
1688 case HCI_OP_READ_CLASS_OF_DEV:
1689 hci_cc_read_class_of_dev(hdev, skb);
1690 break;
1691
1692 case HCI_OP_WRITE_CLASS_OF_DEV:
1693 hci_cc_write_class_of_dev(hdev, skb);
1694 break;
1695
1696 case HCI_OP_READ_VOICE_SETTING:
1697 hci_cc_read_voice_setting(hdev, skb);
1698 break;
1699
1700 case HCI_OP_WRITE_VOICE_SETTING:
1701 hci_cc_write_voice_setting(hdev, skb);
1702 break;
1703
1704 case HCI_OP_HOST_BUFFER_SIZE:
1705 hci_cc_host_buffer_size(hdev, skb);
1706 break;
1707
Marcel Holtmann333140b2008-07-14 20:13:48 +02001708 case HCI_OP_READ_SSP_MODE:
1709 hci_cc_read_ssp_mode(hdev, skb);
1710 break;
1711
1712 case HCI_OP_WRITE_SSP_MODE:
1713 hci_cc_write_ssp_mode(hdev, skb);
1714 break;
1715
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001716 case HCI_OP_READ_LOCAL_VERSION:
1717 hci_cc_read_local_version(hdev, skb);
1718 break;
1719
1720 case HCI_OP_READ_LOCAL_COMMANDS:
1721 hci_cc_read_local_commands(hdev, skb);
1722 break;
1723
1724 case HCI_OP_READ_LOCAL_FEATURES:
1725 hci_cc_read_local_features(hdev, skb);
1726 break;
1727
1728 case HCI_OP_READ_BUFFER_SIZE:
1729 hci_cc_read_buffer_size(hdev, skb);
1730 break;
1731
1732 case HCI_OP_READ_BD_ADDR:
1733 hci_cc_read_bd_addr(hdev, skb);
1734 break;
1735
Johan Hedberg23bb5762010-12-21 23:01:27 +02001736 case HCI_OP_WRITE_CA_TIMEOUT:
1737 hci_cc_write_ca_timeout(hdev, skb);
1738 break;
1739
Johan Hedbergb0916ea2011-01-10 13:44:55 +02001740 case HCI_OP_DELETE_STORED_LINK_KEY:
1741 hci_cc_delete_stored_link_key(hdev, skb);
1742 break;
1743
Johan Hedbergd5859e22011-01-25 01:19:58 +02001744 case HCI_OP_SET_EVENT_MASK:
1745 hci_cc_set_event_mask(hdev, skb);
1746 break;
1747
1748 case HCI_OP_WRITE_INQUIRY_MODE:
1749 hci_cc_write_inquiry_mode(hdev, skb);
1750 break;
1751
1752 case HCI_OP_READ_INQ_RSP_TX_POWER:
1753 hci_cc_read_inq_rsp_tx_power(hdev, skb);
1754 break;
1755
1756 case HCI_OP_SET_EVENT_FLT:
1757 hci_cc_set_event_flt(hdev, skb);
1758 break;
1759
Johan Hedberg980e1a52011-01-22 06:10:07 +02001760 case HCI_OP_PIN_CODE_REPLY:
1761 hci_cc_pin_code_reply(hdev, skb);
1762 break;
1763
1764 case HCI_OP_PIN_CODE_NEG_REPLY:
1765 hci_cc_pin_code_neg_reply(hdev, skb);
1766 break;
1767
Szymon Jancc35938b2011-03-22 13:12:21 +01001768 case HCI_OP_READ_LOCAL_OOB_DATA:
1769 hci_cc_read_local_oob_data_reply(hdev, skb);
1770 break;
1771
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001772 case HCI_OP_LE_READ_BUFFER_SIZE:
1773 hci_cc_le_read_buffer_size(hdev, skb);
1774 break;
1775
Johan Hedberga5c29682011-02-19 12:05:57 -03001776 case HCI_OP_USER_CONFIRM_REPLY:
1777 hci_cc_user_confirm_reply(hdev, skb);
1778 break;
1779
1780 case HCI_OP_USER_CONFIRM_NEG_REPLY:
1781 hci_cc_user_confirm_neg_reply(hdev, skb);
1782 break;
1783
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001784 default:
1785 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1786 break;
1787 }
1788
Ville Tervo6bd32322011-02-16 16:32:41 +02001789 if (ev->opcode != HCI_OP_NOP)
1790 del_timer(&hdev->cmd_timer);
1791
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001792 if (ev->ncmd) {
1793 atomic_set(&hdev->cmd_cnt, 1);
1794 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001795 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001796 }
1797}
1798
1799static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1800{
1801 struct hci_ev_cmd_status *ev = (void *) skb->data;
1802 __u16 opcode;
1803
1804 skb_pull(skb, sizeof(*ev));
1805
1806 opcode = __le16_to_cpu(ev->opcode);
1807
1808 switch (opcode) {
1809 case HCI_OP_INQUIRY:
1810 hci_cs_inquiry(hdev, ev->status);
1811 break;
1812
1813 case HCI_OP_CREATE_CONN:
1814 hci_cs_create_conn(hdev, ev->status);
1815 break;
1816
1817 case HCI_OP_ADD_SCO:
1818 hci_cs_add_sco(hdev, ev->status);
1819 break;
1820
Marcel Holtmannf8558552008-07-14 20:13:49 +02001821 case HCI_OP_AUTH_REQUESTED:
1822 hci_cs_auth_requested(hdev, ev->status);
1823 break;
1824
1825 case HCI_OP_SET_CONN_ENCRYPT:
1826 hci_cs_set_conn_encrypt(hdev, ev->status);
1827 break;
1828
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001829 case HCI_OP_REMOTE_NAME_REQ:
1830 hci_cs_remote_name_req(hdev, ev->status);
1831 break;
1832
Marcel Holtmann769be972008-07-14 20:13:49 +02001833 case HCI_OP_READ_REMOTE_FEATURES:
1834 hci_cs_read_remote_features(hdev, ev->status);
1835 break;
1836
1837 case HCI_OP_READ_REMOTE_EXT_FEATURES:
1838 hci_cs_read_remote_ext_features(hdev, ev->status);
1839 break;
1840
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001841 case HCI_OP_SETUP_SYNC_CONN:
1842 hci_cs_setup_sync_conn(hdev, ev->status);
1843 break;
1844
1845 case HCI_OP_SNIFF_MODE:
1846 hci_cs_sniff_mode(hdev, ev->status);
1847 break;
1848
1849 case HCI_OP_EXIT_SNIFF_MODE:
1850 hci_cs_exit_sniff_mode(hdev, ev->status);
1851 break;
1852
Johan Hedberg8962ee72011-01-20 12:40:27 +02001853 case HCI_OP_DISCONNECT:
1854 if (ev->status != 0)
1855 mgmt_disconnect_failed(hdev->id);
1856 break;
1857
Ville Tervofcd89c02011-02-10 22:38:47 -03001858 case HCI_OP_LE_CREATE_CONN:
1859 hci_cs_le_create_conn(hdev, ev->status);
1860 break;
1861
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001862 default:
1863 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1864 break;
1865 }
1866
Ville Tervo6bd32322011-02-16 16:32:41 +02001867 if (ev->opcode != HCI_OP_NOP)
1868 del_timer(&hdev->cmd_timer);
1869
Gustavo F. Padovan10572132011-03-16 15:36:29 -03001870 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001871 atomic_set(&hdev->cmd_cnt, 1);
1872 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001873 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001874 }
1875}
1876
1877static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1878{
1879 struct hci_ev_role_change *ev = (void *) skb->data;
1880 struct hci_conn *conn;
1881
1882 BT_DBG("%s status %d", hdev->name, ev->status);
1883
1884 hci_dev_lock(hdev);
1885
1886 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1887 if (conn) {
1888 if (!ev->status) {
1889 if (ev->role)
1890 conn->link_mode &= ~HCI_LM_MASTER;
1891 else
1892 conn->link_mode |= HCI_LM_MASTER;
1893 }
1894
1895 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1896
1897 hci_role_switch_cfm(conn, ev->status, ev->role);
1898 }
1899
1900 hci_dev_unlock(hdev);
1901}
1902
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
1904{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001905 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001906 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 int i;
1908
1909 skb_pull(skb, sizeof(*ev));
1910
1911 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
1912
1913 if (skb->len < ev->num_hndl * 4) {
1914 BT_DBG("%s bad parameters", hdev->name);
1915 return;
1916 }
1917
1918 tasklet_disable(&hdev->tx_task);
1919
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001920 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 struct hci_conn *conn;
1922 __u16 handle, count;
1923
Harvey Harrison83985312008-05-02 16:25:46 -07001924 handle = get_unaligned_le16(ptr++);
1925 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926
1927 conn = hci_conn_hash_lookup_handle(hdev, handle);
1928 if (conn) {
1929 conn->sent -= count;
1930
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001931 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001932 hdev->acl_cnt += count;
1933 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934 hdev->acl_cnt = hdev->acl_pkts;
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001935 } else if (conn->type == LE_LINK) {
1936 if (hdev->le_pkts) {
1937 hdev->le_cnt += count;
1938 if (hdev->le_cnt > hdev->le_pkts)
1939 hdev->le_cnt = hdev->le_pkts;
1940 } else {
1941 hdev->acl_cnt += count;
1942 if (hdev->acl_cnt > hdev->acl_pkts)
1943 hdev->acl_cnt = hdev->acl_pkts;
1944 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001945 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001946 hdev->sco_cnt += count;
1947 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001948 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949 }
1950 }
1951 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001952
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001953 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954
1955 tasklet_enable(&hdev->tx_task);
1956}
1957
Marcel Holtmann04837f62006-07-03 10:02:33 +02001958static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001960 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001961 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962
1963 BT_DBG("%s status %d", hdev->name, ev->status);
1964
1965 hci_dev_lock(hdev);
1966
Marcel Holtmann04837f62006-07-03 10:02:33 +02001967 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1968 if (conn) {
1969 conn->mode = ev->mode;
1970 conn->interval = __le16_to_cpu(ev->interval);
1971
1972 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
1973 if (conn->mode == HCI_CM_ACTIVE)
1974 conn->power_save = 1;
1975 else
1976 conn->power_save = 0;
1977 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001978
1979 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1980 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001981 }
1982
1983 hci_dev_unlock(hdev);
1984}
1985
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1987{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001988 struct hci_ev_pin_code_req *ev = (void *) skb->data;
1989 struct hci_conn *conn;
1990
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001991 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001992
1993 hci_dev_lock(hdev);
1994
1995 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Marcel Holtmann3d7a9d12009-05-09 12:09:21 -07001996 if (conn && conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001997 hci_conn_hold(conn);
1998 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1999 hci_conn_put(conn);
2000 }
2001
Johan Hedberg03b555e2011-01-04 15:40:05 +02002002 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
2003 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2004 sizeof(ev->bdaddr), &ev->bdaddr);
2005
Johan Hedberg980e1a52011-01-22 06:10:07 +02002006 if (test_bit(HCI_MGMT, &hdev->flags))
2007 mgmt_pin_code_request(hdev->id, &ev->bdaddr);
2008
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002009 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010}
2011
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2013{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002014 struct hci_ev_link_key_req *ev = (void *) skb->data;
2015 struct hci_cp_link_key_reply cp;
2016 struct hci_conn *conn;
2017 struct link_key *key;
2018
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002019 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002020
2021 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
2022 return;
2023
2024 hci_dev_lock(hdev);
2025
2026 key = hci_find_link_key(hdev, &ev->bdaddr);
2027 if (!key) {
2028 BT_DBG("%s link key not found for %s", hdev->name,
2029 batostr(&ev->bdaddr));
2030 goto not_found;
2031 }
2032
2033 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2034 batostr(&ev->bdaddr));
2035
2036 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) {
2037 BT_DBG("%s ignoring debug key", hdev->name);
2038 goto not_found;
2039 }
2040
2041 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2042
2043 if (key->type == 0x04 && conn && conn->auth_type != 0xff &&
2044 (conn->auth_type & 0x01)) {
2045 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2046 goto not_found;
2047 }
2048
2049 bacpy(&cp.bdaddr, &ev->bdaddr);
2050 memcpy(cp.link_key, key->val, 16);
2051
2052 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2053
2054 hci_dev_unlock(hdev);
2055
2056 return;
2057
2058not_found:
2059 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2060 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061}
2062
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2064{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002065 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2066 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002067 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002068
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002069 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002070
2071 hci_dev_lock(hdev);
2072
2073 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2074 if (conn) {
2075 hci_conn_hold(conn);
2076 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002077 pin_len = conn->pin_length;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002078 hci_conn_put(conn);
2079 }
2080
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002081 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
2082 hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key,
2083 ev->key_type, pin_len);
2084
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002085 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086}
2087
Marcel Holtmann04837f62006-07-03 10:02:33 +02002088static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2089{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002090 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002091 struct hci_conn *conn;
2092
2093 BT_DBG("%s status %d", hdev->name, ev->status);
2094
2095 hci_dev_lock(hdev);
2096
2097 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098 if (conn && !ev->status) {
2099 struct inquiry_entry *ie;
2100
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002101 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2102 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103 ie->data.clock_offset = ev->clock_offset;
2104 ie->timestamp = jiffies;
2105 }
2106 }
2107
2108 hci_dev_unlock(hdev);
2109}
2110
Marcel Holtmanna8746412008-07-14 20:13:46 +02002111static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2112{
2113 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2114 struct hci_conn *conn;
2115
2116 BT_DBG("%s status %d", hdev->name, ev->status);
2117
2118 hci_dev_lock(hdev);
2119
2120 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2121 if (conn && !ev->status)
2122 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2123
2124 hci_dev_unlock(hdev);
2125}
2126
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002127static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2128{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002129 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002130 struct inquiry_entry *ie;
2131
2132 BT_DBG("%s", hdev->name);
2133
2134 hci_dev_lock(hdev);
2135
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002136 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2137 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002138 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2139 ie->timestamp = jiffies;
2140 }
2141
2142 hci_dev_unlock(hdev);
2143}
2144
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002145static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2146{
2147 struct inquiry_data data;
2148 int num_rsp = *((__u8 *) skb->data);
2149
2150 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2151
2152 if (!num_rsp)
2153 return;
2154
2155 hci_dev_lock(hdev);
2156
2157 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002158 struct inquiry_info_with_rssi_and_pscan_mode *info;
2159 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002160
2161 for (; num_rsp; num_rsp--) {
2162 bacpy(&data.bdaddr, &info->bdaddr);
2163 data.pscan_rep_mode = info->pscan_rep_mode;
2164 data.pscan_period_mode = info->pscan_period_mode;
2165 data.pscan_mode = info->pscan_mode;
2166 memcpy(data.dev_class, info->dev_class, 3);
2167 data.clock_offset = info->clock_offset;
2168 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002169 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002170 info++;
2171 hci_inquiry_cache_update(hdev, &data);
2172 }
2173 } else {
2174 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2175
2176 for (; num_rsp; num_rsp--) {
2177 bacpy(&data.bdaddr, &info->bdaddr);
2178 data.pscan_rep_mode = info->pscan_rep_mode;
2179 data.pscan_period_mode = info->pscan_period_mode;
2180 data.pscan_mode = 0x00;
2181 memcpy(data.dev_class, info->dev_class, 3);
2182 data.clock_offset = info->clock_offset;
2183 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002184 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002185 info++;
2186 hci_inquiry_cache_update(hdev, &data);
2187 }
2188 }
2189
2190 hci_dev_unlock(hdev);
2191}
2192
2193static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2194{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002195 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2196 struct hci_conn *conn;
2197
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002198 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002199
Marcel Holtmann41a96212008-07-14 20:13:48 +02002200 hci_dev_lock(hdev);
2201
2202 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002203 if (!conn)
2204 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002205
Johan Hedbergccd556f2010-11-10 17:11:51 +02002206 if (!ev->status && ev->page == 0x01) {
2207 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002208
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002209 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2210 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002211 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002212
Johan Hedbergccd556f2010-11-10 17:11:51 +02002213 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002214 }
2215
Johan Hedbergccd556f2010-11-10 17:11:51 +02002216 if (conn->state != BT_CONFIG)
2217 goto unlock;
2218
Johan Hedberg127178d2010-11-18 22:22:29 +02002219 if (!ev->status) {
2220 struct hci_cp_remote_name_req cp;
2221 memset(&cp, 0, sizeof(cp));
2222 bacpy(&cp.bdaddr, &conn->dst);
2223 cp.pscan_rep_mode = 0x02;
2224 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2225 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002226
Johan Hedberg127178d2010-11-18 22:22:29 +02002227 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002228 conn->state = BT_CONNECTED;
2229 hci_proto_connect_cfm(conn, ev->status);
2230 hci_conn_put(conn);
2231 }
2232
2233unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002234 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002235}
2236
2237static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2238{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002239 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2240 struct hci_conn *conn;
2241
2242 BT_DBG("%s status %d", hdev->name, ev->status);
2243
2244 hci_dev_lock(hdev);
2245
2246 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002247 if (!conn) {
2248 if (ev->link_type == ESCO_LINK)
2249 goto unlock;
2250
2251 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2252 if (!conn)
2253 goto unlock;
2254
2255 conn->type = SCO_LINK;
2256 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002257
Marcel Holtmann732547f2009-04-19 19:14:14 +02002258 switch (ev->status) {
2259 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002260 conn->handle = __le16_to_cpu(ev->handle);
2261 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002262
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002263 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002264 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002265 break;
2266
Stephen Coe705e5712010-02-16 11:29:44 -05002267 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002268 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002269 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002270 case 0x1f: /* Unspecified error */
2271 if (conn->out && conn->attempt < 2) {
2272 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2273 (hdev->esco_type & EDR_ESCO_MASK);
2274 hci_setup_sync(conn, conn->link->handle);
2275 goto unlock;
2276 }
2277 /* fall through */
2278
2279 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002280 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002281 break;
2282 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002283
2284 hci_proto_connect_cfm(conn, ev->status);
2285 if (ev->status)
2286 hci_conn_del(conn);
2287
2288unlock:
2289 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002290}
2291
2292static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2293{
2294 BT_DBG("%s", hdev->name);
2295}
2296
Marcel Holtmann04837f62006-07-03 10:02:33 +02002297static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2298{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002299 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002300
2301 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002302}
2303
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002304static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2305{
2306 struct inquiry_data data;
2307 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2308 int num_rsp = *((__u8 *) skb->data);
2309
2310 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2311
2312 if (!num_rsp)
2313 return;
2314
2315 hci_dev_lock(hdev);
2316
2317 for (; num_rsp; num_rsp--) {
2318 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002319 data.pscan_rep_mode = info->pscan_rep_mode;
2320 data.pscan_period_mode = info->pscan_period_mode;
2321 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002322 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002323 data.clock_offset = info->clock_offset;
2324 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002325 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002326 info++;
2327 hci_inquiry_cache_update(hdev, &data);
2328 }
2329
2330 hci_dev_unlock(hdev);
2331}
2332
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002333static inline u8 hci_get_auth_req(struct hci_conn *conn)
2334{
2335 /* If remote requests dedicated bonding follow that lead */
2336 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2337 /* If both remote and local IO capabilities allow MITM
2338 * protection then require it, otherwise don't */
2339 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2340 return 0x02;
2341 else
2342 return 0x03;
2343 }
2344
2345 /* If remote requests no-bonding follow that lead */
2346 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
2347 return 0x00;
2348
2349 return conn->auth_type;
2350}
2351
Marcel Holtmann04936842008-07-14 20:13:48 +02002352static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2353{
2354 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2355 struct hci_conn *conn;
2356
2357 BT_DBG("%s", hdev->name);
2358
2359 hci_dev_lock(hdev);
2360
2361 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002362 if (!conn)
2363 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002364
Johan Hedberg03b555e2011-01-04 15:40:05 +02002365 hci_conn_hold(conn);
2366
2367 if (!test_bit(HCI_MGMT, &hdev->flags))
2368 goto unlock;
2369
2370 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
2371 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002372 struct hci_cp_io_capability_reply cp;
2373
2374 bacpy(&cp.bdaddr, &ev->bdaddr);
2375 cp.capability = conn->io_capability;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002376 cp.authentication = hci_get_auth_req(conn);
2377
Szymon Jancce85ee12011-03-22 13:12:23 +01002378 if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
2379 hci_find_remote_oob_data(hdev, &conn->dst))
2380 cp.oob_data = 0x01;
2381 else
2382 cp.oob_data = 0x00;
2383
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002384 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2385 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002386 } else {
2387 struct hci_cp_io_capability_neg_reply cp;
2388
2389 bacpy(&cp.bdaddr, &ev->bdaddr);
2390 cp.reason = 0x16; /* Pairing not allowed */
2391
2392 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2393 sizeof(cp), &cp);
2394 }
2395
2396unlock:
2397 hci_dev_unlock(hdev);
2398}
2399
2400static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2401{
2402 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2403 struct hci_conn *conn;
2404
2405 BT_DBG("%s", hdev->name);
2406
2407 hci_dev_lock(hdev);
2408
2409 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2410 if (!conn)
2411 goto unlock;
2412
2413 hci_conn_hold(conn);
2414
2415 conn->remote_cap = ev->capability;
2416 conn->remote_oob = ev->oob_data;
2417 conn->remote_auth = ev->authentication;
2418
2419unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002420 hci_dev_unlock(hdev);
2421}
2422
Johan Hedberga5c29682011-02-19 12:05:57 -03002423static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2424 struct sk_buff *skb)
2425{
2426 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
2427
2428 BT_DBG("%s", hdev->name);
2429
2430 hci_dev_lock(hdev);
2431
2432 if (test_bit(HCI_MGMT, &hdev->flags))
2433 mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
2434
2435 hci_dev_unlock(hdev);
2436}
2437
Marcel Holtmann04936842008-07-14 20:13:48 +02002438static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2439{
2440 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
2441 struct hci_conn *conn;
2442
2443 BT_DBG("%s", hdev->name);
2444
2445 hci_dev_lock(hdev);
2446
2447 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03002448 if (!conn)
2449 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002450
Johan Hedberg2a611692011-02-19 12:06:00 -03002451 /* To avoid duplicate auth_failed events to user space we check
2452 * the HCI_CONN_AUTH_PEND flag which will be set if we
2453 * initiated the authentication. A traditional auth_complete
2454 * event gets always produced as initiator and is also mapped to
2455 * the mgmt_auth_failed event */
2456 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
2457 mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
2458
2459 hci_conn_put(conn);
2460
2461unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002462 hci_dev_unlock(hdev);
2463}
2464
Marcel Holtmann41a96212008-07-14 20:13:48 +02002465static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2466{
2467 struct hci_ev_remote_host_features *ev = (void *) skb->data;
2468 struct inquiry_entry *ie;
2469
2470 BT_DBG("%s", hdev->name);
2471
2472 hci_dev_lock(hdev);
2473
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002474 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2475 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02002476 ie->data.ssp_mode = (ev->features[0] & 0x01);
2477
2478 hci_dev_unlock(hdev);
2479}
2480
Szymon Janc2763eda2011-03-22 13:12:22 +01002481static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
2482 struct sk_buff *skb)
2483{
2484 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
2485 struct oob_data *data;
2486
2487 BT_DBG("%s", hdev->name);
2488
2489 hci_dev_lock(hdev);
2490
2491 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
2492 if (data) {
2493 struct hci_cp_remote_oob_data_reply cp;
2494
2495 bacpy(&cp.bdaddr, &ev->bdaddr);
2496 memcpy(cp.hash, data->hash, sizeof(cp.hash));
2497 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
2498
2499 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
2500 &cp);
2501 } else {
2502 struct hci_cp_remote_oob_data_neg_reply cp;
2503
2504 bacpy(&cp.bdaddr, &ev->bdaddr);
2505 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
2506 &cp);
2507 }
2508
2509 hci_dev_unlock(hdev);
2510}
2511
Ville Tervofcd89c02011-02-10 22:38:47 -03002512static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2513{
2514 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2515 struct hci_conn *conn;
2516
2517 BT_DBG("%s status %d", hdev->name, ev->status);
2518
2519 hci_dev_lock(hdev);
2520
2521 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03002522 if (!conn) {
2523 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
2524 if (!conn) {
2525 BT_ERR("No memory for new connection");
2526 hci_dev_unlock(hdev);
2527 return;
2528 }
2529 }
Ville Tervofcd89c02011-02-10 22:38:47 -03002530
2531 if (ev->status) {
2532 hci_proto_connect_cfm(conn, ev->status);
2533 conn->state = BT_CLOSED;
2534 hci_conn_del(conn);
2535 goto unlock;
2536 }
2537
2538 conn->handle = __le16_to_cpu(ev->handle);
2539 conn->state = BT_CONNECTED;
2540
2541 hci_conn_hold_device(conn);
2542 hci_conn_add_sysfs(conn);
2543
2544 hci_proto_connect_cfm(conn, ev->status);
2545
2546unlock:
2547 hci_dev_unlock(hdev);
2548}
2549
2550static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
2551{
2552 struct hci_ev_le_meta *le_ev = (void *) skb->data;
2553
2554 skb_pull(skb, sizeof(*le_ev));
2555
2556 switch (le_ev->subevent) {
2557 case HCI_EV_LE_CONN_COMPLETE:
2558 hci_le_conn_complete_evt(hdev, skb);
2559 break;
2560
2561 default:
2562 break;
2563 }
2564}
2565
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
2567{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002568 struct hci_event_hdr *hdr = (void *) skb->data;
2569 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570
2571 skb_pull(skb, HCI_EVENT_HDR_SIZE);
2572
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002573 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002574 case HCI_EV_INQUIRY_COMPLETE:
2575 hci_inquiry_complete_evt(hdev, skb);
2576 break;
2577
2578 case HCI_EV_INQUIRY_RESULT:
2579 hci_inquiry_result_evt(hdev, skb);
2580 break;
2581
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002582 case HCI_EV_CONN_COMPLETE:
2583 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02002584 break;
2585
Linus Torvalds1da177e2005-04-16 15:20:36 -07002586 case HCI_EV_CONN_REQUEST:
2587 hci_conn_request_evt(hdev, skb);
2588 break;
2589
Linus Torvalds1da177e2005-04-16 15:20:36 -07002590 case HCI_EV_DISCONN_COMPLETE:
2591 hci_disconn_complete_evt(hdev, skb);
2592 break;
2593
Linus Torvalds1da177e2005-04-16 15:20:36 -07002594 case HCI_EV_AUTH_COMPLETE:
2595 hci_auth_complete_evt(hdev, skb);
2596 break;
2597
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002598 case HCI_EV_REMOTE_NAME:
2599 hci_remote_name_evt(hdev, skb);
2600 break;
2601
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602 case HCI_EV_ENCRYPT_CHANGE:
2603 hci_encrypt_change_evt(hdev, skb);
2604 break;
2605
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002606 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
2607 hci_change_link_key_complete_evt(hdev, skb);
2608 break;
2609
2610 case HCI_EV_REMOTE_FEATURES:
2611 hci_remote_features_evt(hdev, skb);
2612 break;
2613
2614 case HCI_EV_REMOTE_VERSION:
2615 hci_remote_version_evt(hdev, skb);
2616 break;
2617
2618 case HCI_EV_QOS_SETUP_COMPLETE:
2619 hci_qos_setup_complete_evt(hdev, skb);
2620 break;
2621
2622 case HCI_EV_CMD_COMPLETE:
2623 hci_cmd_complete_evt(hdev, skb);
2624 break;
2625
2626 case HCI_EV_CMD_STATUS:
2627 hci_cmd_status_evt(hdev, skb);
2628 break;
2629
2630 case HCI_EV_ROLE_CHANGE:
2631 hci_role_change_evt(hdev, skb);
2632 break;
2633
2634 case HCI_EV_NUM_COMP_PKTS:
2635 hci_num_comp_pkts_evt(hdev, skb);
2636 break;
2637
2638 case HCI_EV_MODE_CHANGE:
2639 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640 break;
2641
2642 case HCI_EV_PIN_CODE_REQ:
2643 hci_pin_code_request_evt(hdev, skb);
2644 break;
2645
2646 case HCI_EV_LINK_KEY_REQ:
2647 hci_link_key_request_evt(hdev, skb);
2648 break;
2649
2650 case HCI_EV_LINK_KEY_NOTIFY:
2651 hci_link_key_notify_evt(hdev, skb);
2652 break;
2653
2654 case HCI_EV_CLOCK_OFFSET:
2655 hci_clock_offset_evt(hdev, skb);
2656 break;
2657
Marcel Holtmanna8746412008-07-14 20:13:46 +02002658 case HCI_EV_PKT_TYPE_CHANGE:
2659 hci_pkt_type_change_evt(hdev, skb);
2660 break;
2661
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002662 case HCI_EV_PSCAN_REP_MODE:
2663 hci_pscan_rep_mode_evt(hdev, skb);
2664 break;
2665
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002666 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
2667 hci_inquiry_result_with_rssi_evt(hdev, skb);
2668 break;
2669
2670 case HCI_EV_REMOTE_EXT_FEATURES:
2671 hci_remote_ext_features_evt(hdev, skb);
2672 break;
2673
2674 case HCI_EV_SYNC_CONN_COMPLETE:
2675 hci_sync_conn_complete_evt(hdev, skb);
2676 break;
2677
2678 case HCI_EV_SYNC_CONN_CHANGED:
2679 hci_sync_conn_changed_evt(hdev, skb);
2680 break;
2681
Marcel Holtmann04837f62006-07-03 10:02:33 +02002682 case HCI_EV_SNIFF_SUBRATE:
2683 hci_sniff_subrate_evt(hdev, skb);
2684 break;
2685
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002686 case HCI_EV_EXTENDED_INQUIRY_RESULT:
2687 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688 break;
2689
Marcel Holtmann04936842008-07-14 20:13:48 +02002690 case HCI_EV_IO_CAPA_REQUEST:
2691 hci_io_capa_request_evt(hdev, skb);
2692 break;
2693
Johan Hedberg03b555e2011-01-04 15:40:05 +02002694 case HCI_EV_IO_CAPA_REPLY:
2695 hci_io_capa_reply_evt(hdev, skb);
2696 break;
2697
Johan Hedberga5c29682011-02-19 12:05:57 -03002698 case HCI_EV_USER_CONFIRM_REQUEST:
2699 hci_user_confirm_request_evt(hdev, skb);
2700 break;
2701
Marcel Holtmann04936842008-07-14 20:13:48 +02002702 case HCI_EV_SIMPLE_PAIR_COMPLETE:
2703 hci_simple_pair_complete_evt(hdev, skb);
2704 break;
2705
Marcel Holtmann41a96212008-07-14 20:13:48 +02002706 case HCI_EV_REMOTE_HOST_FEATURES:
2707 hci_remote_host_features_evt(hdev, skb);
2708 break;
2709
Ville Tervofcd89c02011-02-10 22:38:47 -03002710 case HCI_EV_LE_META:
2711 hci_le_meta_evt(hdev, skb);
2712 break;
2713
Szymon Janc2763eda2011-03-22 13:12:22 +01002714 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
2715 hci_remote_oob_data_request_evt(hdev, skb);
2716 break;
2717
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002718 default:
2719 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002720 break;
2721 }
2722
2723 kfree_skb(skb);
2724 hdev->stat.evt_rx++;
2725}
2726
2727/* Generate internal stack event */
2728void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
2729{
2730 struct hci_event_hdr *hdr;
2731 struct hci_ev_stack_internal *ev;
2732 struct sk_buff *skb;
2733
2734 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
2735 if (!skb)
2736 return;
2737
2738 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
2739 hdr->evt = HCI_EV_STACK_INTERNAL;
2740 hdr->plen = sizeof(*ev) + dlen;
2741
2742 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
2743 ev->type = type;
2744 memcpy(ev->data, data, dlen);
2745
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002746 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07002747 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002748
Marcel Holtmann0d48d932005-08-09 20:30:28 -07002749 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02002751 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002752 kfree_skb(skb);
2753}