blob: d8fa65709aedda32fe91b44fda0c5fcc4d153577 [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
Andre Guedese6100a22011-06-30 19:20:54 -030048static int enable_le;
49
Linus Torvalds1da177e2005-04-16 15:20:36 -070050/* Handle HCI Event packets */
51
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070053{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020054 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Marcel Holtmanna9de9242007-10-20 13:33:56 +020056 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Marcel Holtmanna9de9242007-10-20 13:33:56 +020058 if (status)
59 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
Oliver Neukum2d20a262011-08-30 15:52:18 +020061 if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) &&
62 test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg314b2382011-04-27 10:29:57 -040063 mgmt_discovering(hdev->id, 0);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010064
Johan Hedberg23bb5762010-12-21 23:01:27 +020065 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010066
Marcel Holtmanna9de9242007-10-20 13:33:56 +020067 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070068}
69
Marcel Holtmanna9de9242007-10-20 13:33:56 +020070static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070071{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020072 __u8 status = *((__u8 *) skb->data);
73
74 BT_DBG("%s status 0x%x", hdev->name, status);
75
76 if (status)
77 return;
78
Oliver Neukum2d20a262011-08-30 15:52:18 +020079 if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) &&
80 test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg314b2382011-04-27 10:29:57 -040081 mgmt_discovering(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020082
83 hci_conn_check_pending(hdev);
84}
85
86static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
87{
88 BT_DBG("%s", hdev->name);
89}
90
91static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
92{
93 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
Marcel Holtmanna9de9242007-10-20 13:33:56 +020096 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Marcel Holtmanna9de9242007-10-20 13:33:56 +020098 if (rp->status)
99 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200101 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200103 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
104 if (conn) {
105 if (rp->role)
106 conn->link_mode &= ~HCI_LM_MASTER;
107 else
108 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200110
111 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112}
113
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200114static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
115{
116 struct hci_rp_read_link_policy *rp = (void *) skb->data;
117 struct hci_conn *conn;
118
119 BT_DBG("%s status 0x%x", hdev->name, rp->status);
120
121 if (rp->status)
122 return;
123
124 hci_dev_lock(hdev);
125
126 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
127 if (conn)
128 conn->link_policy = __le16_to_cpu(rp->policy);
129
130 hci_dev_unlock(hdev);
131}
132
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200133static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135 struct hci_rp_write_link_policy *rp = (void *) skb->data;
136 struct hci_conn *conn;
137 void *sent;
138
139 BT_DBG("%s status 0x%x", hdev->name, rp->status);
140
141 if (rp->status)
142 return;
143
144 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
145 if (!sent)
146 return;
147
148 hci_dev_lock(hdev);
149
150 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200151 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700152 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200153
154 hci_dev_unlock(hdev);
155}
156
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200157static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
158{
159 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
160
161 BT_DBG("%s status 0x%x", hdev->name, rp->status);
162
163 if (rp->status)
164 return;
165
166 hdev->link_policy = __le16_to_cpu(rp->policy);
167}
168
169static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
170{
171 __u8 status = *((__u8 *) skb->data);
172 void *sent;
173
174 BT_DBG("%s status 0x%x", hdev->name, status);
175
176 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
177 if (!sent)
178 return;
179
180 if (!status)
181 hdev->link_policy = get_unaligned_le16(sent);
182
Johan Hedberg23bb5762010-12-21 23:01:27 +0200183 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200184}
185
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200186static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
187{
188 __u8 status = *((__u8 *) skb->data);
189
190 BT_DBG("%s status 0x%x", hdev->name, status);
191
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300192 clear_bit(HCI_RESET, &hdev->flags);
193
Johan Hedberg23bb5762010-12-21 23:01:27 +0200194 hci_req_complete(hdev, HCI_OP_RESET, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200195}
196
197static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
198{
199 __u8 status = *((__u8 *) skb->data);
200 void *sent;
201
202 BT_DBG("%s status 0x%x", hdev->name, status);
203
204 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
205 if (!sent)
206 return;
207
Johan Hedbergb312b1612011-03-16 14:29:37 +0200208 if (test_bit(HCI_MGMT, &hdev->flags))
209 mgmt_set_local_name_complete(hdev->id, sent, status);
210
211 if (status)
212 return;
213
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200214 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200215}
216
217static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
218{
219 struct hci_rp_read_local_name *rp = (void *) skb->data;
220
221 BT_DBG("%s status 0x%x", hdev->name, rp->status);
222
223 if (rp->status)
224 return;
225
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200226 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200227}
228
229static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
230{
231 __u8 status = *((__u8 *) skb->data);
232 void *sent;
233
234 BT_DBG("%s status 0x%x", hdev->name, status);
235
236 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
237 if (!sent)
238 return;
239
240 if (!status) {
241 __u8 param = *((__u8 *) sent);
242
243 if (param == AUTH_ENABLED)
244 set_bit(HCI_AUTH, &hdev->flags);
245 else
246 clear_bit(HCI_AUTH, &hdev->flags);
247 }
248
Johan Hedberg23bb5762010-12-21 23:01:27 +0200249 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200250}
251
252static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
253{
254 __u8 status = *((__u8 *) skb->data);
255 void *sent;
256
257 BT_DBG("%s status 0x%x", hdev->name, status);
258
259 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
260 if (!sent)
261 return;
262
263 if (!status) {
264 __u8 param = *((__u8 *) sent);
265
266 if (param)
267 set_bit(HCI_ENCRYPT, &hdev->flags);
268 else
269 clear_bit(HCI_ENCRYPT, &hdev->flags);
270 }
271
Johan Hedberg23bb5762010-12-21 23:01:27 +0200272 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200273}
274
275static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
276{
277 __u8 status = *((__u8 *) skb->data);
278 void *sent;
279
280 BT_DBG("%s status 0x%x", hdev->name, status);
281
282 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
283 if (!sent)
284 return;
285
286 if (!status) {
287 __u8 param = *((__u8 *) sent);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200288 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200289
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200290 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
291 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200292
Johan Hedberg73f22f62010-12-29 16:00:25 +0200293 if (param & SCAN_INQUIRY) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200294 set_bit(HCI_ISCAN, &hdev->flags);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200295 if (!old_iscan)
296 mgmt_discoverable(hdev->id, 1);
297 } else if (old_iscan)
Johan Hedberg73f22f62010-12-29 16:00:25 +0200298 mgmt_discoverable(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200299
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200300 if (param & SCAN_PAGE) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200301 set_bit(HCI_PSCAN, &hdev->flags);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200302 if (!old_pscan)
303 mgmt_connectable(hdev->id, 1);
304 } else if (old_pscan)
305 mgmt_connectable(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200306 }
307
Johan Hedberg23bb5762010-12-21 23:01:27 +0200308 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200309}
310
311static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
312{
313 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
314
315 BT_DBG("%s status 0x%x", hdev->name, rp->status);
316
317 if (rp->status)
318 return;
319
320 memcpy(hdev->dev_class, rp->dev_class, 3);
321
322 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
323 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
324}
325
326static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
327{
328 __u8 status = *((__u8 *) skb->data);
329 void *sent;
330
331 BT_DBG("%s status 0x%x", hdev->name, status);
332
Marcel Holtmannf383f272008-07-14 20:13:47 +0200333 if (status)
334 return;
335
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200336 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
337 if (!sent)
338 return;
339
Marcel Holtmannf383f272008-07-14 20:13:47 +0200340 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200341}
342
343static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
344{
345 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200347
348 BT_DBG("%s status 0x%x", hdev->name, rp->status);
349
350 if (rp->status)
351 return;
352
353 setting = __le16_to_cpu(rp->voice_setting);
354
Marcel Holtmannf383f272008-07-14 20:13:47 +0200355 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200356 return;
357
358 hdev->voice_setting = setting;
359
360 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
361
362 if (hdev->notify) {
363 tasklet_disable(&hdev->tx_task);
364 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
365 tasklet_enable(&hdev->tx_task);
366 }
367}
368
369static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
370{
371 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200372 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 void *sent;
374
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376
Marcel Holtmannf383f272008-07-14 20:13:47 +0200377 if (status)
378 return;
379
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200380 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
381 if (!sent)
382 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383
Marcel Holtmannf383f272008-07-14 20:13:47 +0200384 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385
Marcel Holtmannf383f272008-07-14 20:13:47 +0200386 if (hdev->voice_setting == setting)
387 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
Marcel Holtmannf383f272008-07-14 20:13:47 +0200389 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390
Marcel Holtmannf383f272008-07-14 20:13:47 +0200391 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
392
393 if (hdev->notify) {
394 tasklet_disable(&hdev->tx_task);
395 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
396 tasklet_enable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 }
398}
399
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200400static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200402 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200404 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405
Johan Hedberg23bb5762010-12-21 23:01:27 +0200406 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407}
408
Marcel Holtmann333140b2008-07-14 20:13:48 +0200409static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
410{
411 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
412
413 BT_DBG("%s status 0x%x", hdev->name, rp->status);
414
415 if (rp->status)
416 return;
417
418 hdev->ssp_mode = rp->mode;
419}
420
421static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
422{
423 __u8 status = *((__u8 *) skb->data);
424 void *sent;
425
426 BT_DBG("%s status 0x%x", hdev->name, status);
427
428 if (status)
429 return;
430
431 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
432 if (!sent)
433 return;
434
435 hdev->ssp_mode = *((__u8 *) sent);
436}
437
Johan Hedbergd5859e22011-01-25 01:19:58 +0200438static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
439{
440 if (hdev->features[6] & LMP_EXT_INQ)
441 return 2;
442
443 if (hdev->features[3] & LMP_RSSI_INQ)
444 return 1;
445
446 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
447 hdev->lmp_subver == 0x0757)
448 return 1;
449
450 if (hdev->manufacturer == 15) {
451 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
452 return 1;
453 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
454 return 1;
455 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
456 return 1;
457 }
458
459 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
460 hdev->lmp_subver == 0x1805)
461 return 1;
462
463 return 0;
464}
465
466static void hci_setup_inquiry_mode(struct hci_dev *hdev)
467{
468 u8 mode;
469
470 mode = hci_get_inquiry_mode(hdev);
471
472 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
473}
474
475static void hci_setup_event_mask(struct hci_dev *hdev)
476{
477 /* The second byte is 0xff instead of 0x9f (two reserved bits
478 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
479 * command otherwise */
480 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
481
Ville Tervo6de6c182011-05-27 11:16:21 +0300482 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
483 * any event mask for pre 1.2 devices */
484 if (hdev->lmp_ver <= 1)
485 return;
486
487 events[4] |= 0x01; /* Flow Specification Complete */
488 events[4] |= 0x02; /* Inquiry Result with RSSI */
489 events[4] |= 0x04; /* Read Remote Extended Features Complete */
490 events[5] |= 0x08; /* Synchronous Connection Complete */
491 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200492
493 if (hdev->features[3] & LMP_RSSI_INQ)
494 events[4] |= 0x04; /* Inquiry Result with RSSI */
495
496 if (hdev->features[5] & LMP_SNIFF_SUBR)
497 events[5] |= 0x20; /* Sniff Subrating */
498
499 if (hdev->features[5] & LMP_PAUSE_ENC)
500 events[5] |= 0x80; /* Encryption Key Refresh Complete */
501
502 if (hdev->features[6] & LMP_EXT_INQ)
503 events[5] |= 0x40; /* Extended Inquiry Result */
504
505 if (hdev->features[6] & LMP_NO_FLUSH)
506 events[7] |= 0x01; /* Enhanced Flush Complete */
507
508 if (hdev->features[7] & LMP_LSTO)
509 events[6] |= 0x80; /* Link Supervision Timeout Changed */
510
511 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
512 events[6] |= 0x01; /* IO Capability Request */
513 events[6] |= 0x02; /* IO Capability Response */
514 events[6] |= 0x04; /* User Confirmation Request */
515 events[6] |= 0x08; /* User Passkey Request */
516 events[6] |= 0x10; /* Remote OOB Data Request */
517 events[6] |= 0x20; /* Simple Pairing Complete */
518 events[7] |= 0x04; /* User Passkey Notification */
519 events[7] |= 0x08; /* Keypress Notification */
520 events[7] |= 0x10; /* Remote Host Supported
521 * Features Notification */
522 }
523
524 if (hdev->features[4] & LMP_LE)
525 events[7] |= 0x20; /* LE Meta-Event */
526
527 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
528}
529
Andre Guedese6100a22011-06-30 19:20:54 -0300530static void hci_set_le_support(struct hci_dev *hdev)
531{
532 struct hci_cp_write_le_host_supported cp;
533
534 memset(&cp, 0, sizeof(cp));
535
536 if (enable_le) {
537 cp.le = 1;
538 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
539 }
540
541 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
542}
543
Johan Hedbergd5859e22011-01-25 01:19:58 +0200544static void hci_setup(struct hci_dev *hdev)
545{
546 hci_setup_event_mask(hdev);
547
548 if (hdev->lmp_ver > 1)
549 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
550
551 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
552 u8 mode = 0x01;
553 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
554 }
555
556 if (hdev->features[3] & LMP_RSSI_INQ)
557 hci_setup_inquiry_mode(hdev);
558
559 if (hdev->features[7] & LMP_INQ_TX_PWR)
560 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300561
562 if (hdev->features[7] & LMP_EXTFEATURES) {
563 struct hci_cp_read_local_ext_features cp;
564
565 cp.page = 0x01;
566 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
567 sizeof(cp), &cp);
568 }
Andre Guedese6100a22011-06-30 19:20:54 -0300569
570 if (hdev->features[4] & LMP_LE)
571 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200572}
573
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200574static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
575{
576 struct hci_rp_read_local_version *rp = (void *) skb->data;
577
578 BT_DBG("%s status 0x%x", hdev->name, rp->status);
579
580 if (rp->status)
581 return;
582
583 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200584 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200585 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200586 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200587 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200588
589 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
590 hdev->manufacturer,
591 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200592
593 if (test_bit(HCI_INIT, &hdev->flags))
594 hci_setup(hdev);
595}
596
597static void hci_setup_link_policy(struct hci_dev *hdev)
598{
599 u16 link_policy = 0;
600
601 if (hdev->features[0] & LMP_RSWITCH)
602 link_policy |= HCI_LP_RSWITCH;
603 if (hdev->features[0] & LMP_HOLD)
604 link_policy |= HCI_LP_HOLD;
605 if (hdev->features[0] & LMP_SNIFF)
606 link_policy |= HCI_LP_SNIFF;
607 if (hdev->features[1] & LMP_PARK)
608 link_policy |= HCI_LP_PARK;
609
610 link_policy = cpu_to_le16(link_policy);
611 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
612 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200613}
614
615static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
616{
617 struct hci_rp_read_local_commands *rp = (void *) skb->data;
618
619 BT_DBG("%s status 0x%x", hdev->name, rp->status);
620
621 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200622 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200623
624 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200625
626 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
627 hci_setup_link_policy(hdev);
628
629done:
630 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200631}
632
633static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
634{
635 struct hci_rp_read_local_features *rp = (void *) skb->data;
636
637 BT_DBG("%s status 0x%x", hdev->name, rp->status);
638
639 if (rp->status)
640 return;
641
642 memcpy(hdev->features, rp->features, 8);
643
644 /* Adjust default settings according to features
645 * supported by device. */
646
647 if (hdev->features[0] & LMP_3SLOT)
648 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
649
650 if (hdev->features[0] & LMP_5SLOT)
651 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
652
653 if (hdev->features[1] & LMP_HV2) {
654 hdev->pkt_type |= (HCI_HV2);
655 hdev->esco_type |= (ESCO_HV2);
656 }
657
658 if (hdev->features[1] & LMP_HV3) {
659 hdev->pkt_type |= (HCI_HV3);
660 hdev->esco_type |= (ESCO_HV3);
661 }
662
663 if (hdev->features[3] & LMP_ESCO)
664 hdev->esco_type |= (ESCO_EV3);
665
666 if (hdev->features[4] & LMP_EV4)
667 hdev->esco_type |= (ESCO_EV4);
668
669 if (hdev->features[4] & LMP_EV5)
670 hdev->esco_type |= (ESCO_EV5);
671
Marcel Holtmannefc76882009-02-06 09:13:37 +0100672 if (hdev->features[5] & LMP_EDR_ESCO_2M)
673 hdev->esco_type |= (ESCO_2EV3);
674
675 if (hdev->features[5] & LMP_EDR_ESCO_3M)
676 hdev->esco_type |= (ESCO_3EV3);
677
678 if (hdev->features[5] & LMP_EDR_3S_ESCO)
679 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
680
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200681 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
682 hdev->features[0], hdev->features[1],
683 hdev->features[2], hdev->features[3],
684 hdev->features[4], hdev->features[5],
685 hdev->features[6], hdev->features[7]);
686}
687
Andre Guedes971e3a42011-06-30 19:20:52 -0300688static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
689 struct sk_buff *skb)
690{
691 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
692
693 BT_DBG("%s status 0x%x", hdev->name, rp->status);
694
695 if (rp->status)
696 return;
697
698 memcpy(hdev->extfeatures, rp->features, 8);
699
700 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
701}
702
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200703static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
704{
705 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
706
707 BT_DBG("%s status 0x%x", hdev->name, rp->status);
708
709 if (rp->status)
710 return;
711
712 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
713 hdev->sco_mtu = rp->sco_mtu;
714 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
715 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
716
717 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
718 hdev->sco_mtu = 64;
719 hdev->sco_pkts = 8;
720 }
721
722 hdev->acl_cnt = hdev->acl_pkts;
723 hdev->sco_cnt = hdev->sco_pkts;
724
725 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
726 hdev->acl_mtu, hdev->acl_pkts,
727 hdev->sco_mtu, hdev->sco_pkts);
728}
729
730static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
731{
732 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
733
734 BT_DBG("%s status 0x%x", hdev->name, rp->status);
735
736 if (!rp->status)
737 bacpy(&hdev->bdaddr, &rp->bdaddr);
738
Johan Hedberg23bb5762010-12-21 23:01:27 +0200739 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
740}
741
742static void hci_cc_write_ca_timeout(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_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200749}
750
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300751static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
752 struct sk_buff *skb)
753{
754 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
755
756 BT_DBG("%s status 0x%x", hdev->name, rp->status);
757
758 if (rp->status)
759 return;
760
761 hdev->amp_status = rp->amp_status;
762 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
763 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
764 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
765 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
766 hdev->amp_type = rp->amp_type;
767 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
768 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
769 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
770 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
771
772 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
773}
774
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200775static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
776 struct sk_buff *skb)
777{
778 __u8 status = *((__u8 *) skb->data);
779
780 BT_DBG("%s status 0x%x", hdev->name, status);
781
782 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
783}
784
Johan Hedbergd5859e22011-01-25 01:19:58 +0200785static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
786{
787 __u8 status = *((__u8 *) skb->data);
788
789 BT_DBG("%s status 0x%x", hdev->name, status);
790
791 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
792}
793
794static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
795 struct sk_buff *skb)
796{
797 __u8 status = *((__u8 *) skb->data);
798
799 BT_DBG("%s status 0x%x", hdev->name, status);
800
801 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
802}
803
804static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
805 struct sk_buff *skb)
806{
807 __u8 status = *((__u8 *) skb->data);
808
809 BT_DBG("%s status 0x%x", hdev->name, status);
810
811 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
812}
813
814static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
815{
816 __u8 status = *((__u8 *) skb->data);
817
818 BT_DBG("%s status 0x%x", hdev->name, status);
819
820 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
821}
822
Johan Hedberg980e1a52011-01-22 06:10:07 +0200823static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
824{
825 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
826 struct hci_cp_pin_code_reply *cp;
827 struct hci_conn *conn;
828
829 BT_DBG("%s status 0x%x", hdev->name, rp->status);
830
831 if (test_bit(HCI_MGMT, &hdev->flags))
832 mgmt_pin_code_reply_complete(hdev->id, &rp->bdaddr, rp->status);
833
834 if (rp->status != 0)
835 return;
836
837 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
838 if (!cp)
839 return;
840
841 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
842 if (conn)
843 conn->pin_length = cp->pin_len;
844}
845
846static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
847{
848 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
849
850 BT_DBG("%s status 0x%x", hdev->name, rp->status);
851
852 if (test_bit(HCI_MGMT, &hdev->flags))
853 mgmt_pin_code_neg_reply_complete(hdev->id, &rp->bdaddr,
854 rp->status);
855}
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300856static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
857 struct sk_buff *skb)
858{
859 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
860
861 BT_DBG("%s status 0x%x", hdev->name, rp->status);
862
863 if (rp->status)
864 return;
865
866 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
867 hdev->le_pkts = rp->le_max_pkt;
868
869 hdev->le_cnt = hdev->le_pkts;
870
871 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
872
873 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
874}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200875
Johan Hedberga5c29682011-02-19 12:05:57 -0300876static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
877{
878 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
879
880 BT_DBG("%s status 0x%x", hdev->name, rp->status);
881
882 if (test_bit(HCI_MGMT, &hdev->flags))
883 mgmt_user_confirm_reply_complete(hdev->id, &rp->bdaddr,
884 rp->status);
885}
886
887static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
888 struct sk_buff *skb)
889{
890 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
891
892 BT_DBG("%s status 0x%x", hdev->name, rp->status);
893
894 if (test_bit(HCI_MGMT, &hdev->flags))
895 mgmt_user_confirm_neg_reply_complete(hdev->id, &rp->bdaddr,
896 rp->status);
897}
898
Szymon Jancc35938b2011-03-22 13:12:21 +0100899static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
900 struct sk_buff *skb)
901{
902 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
903
904 BT_DBG("%s status 0x%x", hdev->name, rp->status);
905
906 mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
907 rp->randomizer, rp->status);
908}
909
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300910static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
911 struct sk_buff *skb)
912{
913 struct hci_cp_le_set_scan_enable *cp;
914 __u8 status = *((__u8 *) skb->data);
915
916 BT_DBG("%s status 0x%x", hdev->name, status);
917
918 if (status)
919 return;
920
921 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
922 if (!cp)
923 return;
924
Andre Guedes35815082011-05-26 16:23:53 -0300925 if (cp->enable == 0x01) {
926 del_timer(&hdev->adv_timer);
Andre Guedesa8f13c82011-09-09 18:56:24 -0300927
928 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300929 hci_adv_entries_clear(hdev);
Andre Guedesa8f13c82011-09-09 18:56:24 -0300930 hci_dev_unlock(hdev);
Andre Guedes35815082011-05-26 16:23:53 -0300931 } else if (cp->enable == 0x00) {
932 mod_timer(&hdev->adv_timer, jiffies + ADV_CLEAR_TIMEOUT);
933 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300934}
935
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -0300936static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
937{
938 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
939
940 BT_DBG("%s status 0x%x", hdev->name, rp->status);
941
942 if (rp->status)
943 return;
944
945 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
946}
947
948static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
949{
950 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
951
952 BT_DBG("%s status 0x%x", hdev->name, rp->status);
953
954 if (rp->status)
955 return;
956
957 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
958}
959
Andre Guedesf9b49302011-06-30 19:20:53 -0300960static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
961 struct sk_buff *skb)
962{
963 struct hci_cp_read_local_ext_features cp;
964 __u8 status = *((__u8 *) skb->data);
965
966 BT_DBG("%s status 0x%x", hdev->name, status);
967
968 if (status)
969 return;
970
971 cp.page = 0x01;
972 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
973}
974
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200975static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
976{
977 BT_DBG("%s status 0x%x", hdev->name, status);
978
979 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +0200980 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200981 hci_conn_check_pending(hdev);
Johan Hedberg164a6e72011-11-01 17:06:44 +0200982 if (test_bit(HCI_MGMT, &hdev->flags))
983 mgmt_inquiry_failed(hdev->id, status);
Johan Hedberg314b2382011-04-27 10:29:57 -0400984 return;
985 }
986
Oliver Neukum2d20a262011-08-30 15:52:18 +0200987 if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags) &&
988 test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg314b2382011-04-27 10:29:57 -0400989 mgmt_discovering(hdev->id, 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200990}
991
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
993{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200994 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200997 BT_DBG("%s status 0x%x", hdev->name, status);
998
999 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 if (!cp)
1001 return;
1002
1003 hci_dev_lock(hdev);
1004
1005 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1006
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001007 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008
1009 if (status) {
1010 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001011 if (status != 0x0c || conn->attempt > 2) {
1012 conn->state = BT_CLOSED;
1013 hci_proto_connect_cfm(conn, status);
1014 hci_conn_del(conn);
1015 } else
1016 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017 }
1018 } else {
1019 if (!conn) {
1020 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1021 if (conn) {
1022 conn->out = 1;
1023 conn->link_mode |= HCI_LM_MASTER;
1024 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001025 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026 }
1027 }
1028
1029 hci_dev_unlock(hdev);
1030}
1031
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001032static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001034 struct hci_cp_add_sco *cp;
1035 struct hci_conn *acl, *sco;
1036 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001038 BT_DBG("%s status 0x%x", hdev->name, status);
1039
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001040 if (!status)
1041 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001043 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1044 if (!cp)
1045 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001047 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001049 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001050
1051 hci_dev_lock(hdev);
1052
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001053 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001054 if (acl) {
1055 sco = acl->link;
1056 if (sco) {
1057 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001058
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001059 hci_proto_connect_cfm(sco, status);
1060 hci_conn_del(sco);
1061 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001062 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001063
1064 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065}
1066
Marcel Holtmannf8558552008-07-14 20:13:49 +02001067static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1068{
1069 struct hci_cp_auth_requested *cp;
1070 struct hci_conn *conn;
1071
1072 BT_DBG("%s status 0x%x", hdev->name, status);
1073
1074 if (!status)
1075 return;
1076
1077 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1078 if (!cp)
1079 return;
1080
1081 hci_dev_lock(hdev);
1082
1083 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1084 if (conn) {
1085 if (conn->state == BT_CONFIG) {
1086 hci_proto_connect_cfm(conn, status);
1087 hci_conn_put(conn);
1088 }
1089 }
1090
1091 hci_dev_unlock(hdev);
1092}
1093
1094static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1095{
1096 struct hci_cp_set_conn_encrypt *cp;
1097 struct hci_conn *conn;
1098
1099 BT_DBG("%s status 0x%x", hdev->name, status);
1100
1101 if (!status)
1102 return;
1103
1104 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1105 if (!cp)
1106 return;
1107
1108 hci_dev_lock(hdev);
1109
1110 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1111 if (conn) {
1112 if (conn->state == BT_CONFIG) {
1113 hci_proto_connect_cfm(conn, status);
1114 hci_conn_put(conn);
1115 }
1116 }
1117
1118 hci_dev_unlock(hdev);
1119}
1120
Johan Hedberg127178d2010-11-18 22:22:29 +02001121static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001122 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001123{
Johan Hedberg392599b2010-11-18 22:22:28 +02001124 if (conn->state != BT_CONFIG || !conn->out)
1125 return 0;
1126
Johan Hedberg765c2a92011-01-19 12:06:52 +05301127 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001128 return 0;
1129
1130 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001131 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedberg392599b2010-11-18 22:22:28 +02001132 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001133 conn->pending_sec_level != BT_SECURITY_HIGH &&
1134 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001135 return 0;
1136
Johan Hedberg392599b2010-11-18 22:22:28 +02001137 return 1;
1138}
1139
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001140static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1141{
Johan Hedberg127178d2010-11-18 22:22:29 +02001142 struct hci_cp_remote_name_req *cp;
1143 struct hci_conn *conn;
1144
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001145 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001146
1147 /* If successful wait for the name req complete event before
1148 * checking for the need to do authentication */
1149 if (!status)
1150 return;
1151
1152 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1153 if (!cp)
1154 return;
1155
1156 hci_dev_lock(hdev);
1157
1158 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001159 if (!conn)
1160 goto unlock;
1161
1162 if (!hci_outgoing_auth_needed(hdev, conn))
1163 goto unlock;
1164
1165 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001166 struct hci_cp_auth_requested cp;
1167 cp.handle = __cpu_to_le16(conn->handle);
1168 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1169 }
1170
Johan Hedberg79c6c702011-04-28 11:28:55 -07001171unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001172 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001173}
1174
Marcel Holtmann769be972008-07-14 20:13:49 +02001175static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1176{
1177 struct hci_cp_read_remote_features *cp;
1178 struct hci_conn *conn;
1179
1180 BT_DBG("%s status 0x%x", hdev->name, status);
1181
1182 if (!status)
1183 return;
1184
1185 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1186 if (!cp)
1187 return;
1188
1189 hci_dev_lock(hdev);
1190
1191 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1192 if (conn) {
1193 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001194 hci_proto_connect_cfm(conn, status);
1195 hci_conn_put(conn);
1196 }
1197 }
1198
1199 hci_dev_unlock(hdev);
1200}
1201
1202static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1203{
1204 struct hci_cp_read_remote_ext_features *cp;
1205 struct hci_conn *conn;
1206
1207 BT_DBG("%s status 0x%x", hdev->name, status);
1208
1209 if (!status)
1210 return;
1211
1212 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1213 if (!cp)
1214 return;
1215
1216 hci_dev_lock(hdev);
1217
1218 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1219 if (conn) {
1220 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001221 hci_proto_connect_cfm(conn, status);
1222 hci_conn_put(conn);
1223 }
1224 }
1225
1226 hci_dev_unlock(hdev);
1227}
1228
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001229static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1230{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001231 struct hci_cp_setup_sync_conn *cp;
1232 struct hci_conn *acl, *sco;
1233 __u16 handle;
1234
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001235 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001236
1237 if (!status)
1238 return;
1239
1240 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1241 if (!cp)
1242 return;
1243
1244 handle = __le16_to_cpu(cp->handle);
1245
1246 BT_DBG("%s handle %d", hdev->name, handle);
1247
1248 hci_dev_lock(hdev);
1249
1250 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001251 if (acl) {
1252 sco = acl->link;
1253 if (sco) {
1254 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001255
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001256 hci_proto_connect_cfm(sco, status);
1257 hci_conn_del(sco);
1258 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001259 }
1260
1261 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001262}
1263
1264static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1265{
1266 struct hci_cp_sniff_mode *cp;
1267 struct hci_conn *conn;
1268
1269 BT_DBG("%s status 0x%x", hdev->name, status);
1270
1271 if (!status)
1272 return;
1273
1274 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1275 if (!cp)
1276 return;
1277
1278 hci_dev_lock(hdev);
1279
1280 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001281 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001282 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1283
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001284 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1285 hci_sco_setup(conn, status);
1286 }
1287
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001288 hci_dev_unlock(hdev);
1289}
1290
1291static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1292{
1293 struct hci_cp_exit_sniff_mode *cp;
1294 struct hci_conn *conn;
1295
1296 BT_DBG("%s status 0x%x", hdev->name, status);
1297
1298 if (!status)
1299 return;
1300
1301 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1302 if (!cp)
1303 return;
1304
1305 hci_dev_lock(hdev);
1306
1307 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001308 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001309 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1310
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001311 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1312 hci_sco_setup(conn, status);
1313 }
1314
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001315 hci_dev_unlock(hdev);
1316}
1317
Ville Tervofcd89c02011-02-10 22:38:47 -03001318static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1319{
1320 struct hci_cp_le_create_conn *cp;
1321 struct hci_conn *conn;
1322
1323 BT_DBG("%s status 0x%x", hdev->name, status);
1324
1325 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1326 if (!cp)
1327 return;
1328
1329 hci_dev_lock(hdev);
1330
1331 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1332
1333 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1334 conn);
1335
1336 if (status) {
1337 if (conn && conn->state == BT_CONNECT) {
1338 conn->state = BT_CLOSED;
1339 hci_proto_connect_cfm(conn, status);
1340 hci_conn_del(conn);
1341 }
1342 } else {
1343 if (!conn) {
1344 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001345 if (conn) {
1346 conn->dst_type = cp->peer_addr_type;
Ville Tervofcd89c02011-02-10 22:38:47 -03001347 conn->out = 1;
Andre Guedes29b79882011-05-31 14:20:54 -03001348 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001349 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001350 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001351 }
1352 }
1353
1354 hci_dev_unlock(hdev);
1355}
1356
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001357static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1358{
1359 BT_DBG("%s status 0x%x", hdev->name, status);
1360}
1361
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001362static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1363{
1364 __u8 status = *((__u8 *) skb->data);
1365
1366 BT_DBG("%s status %d", hdev->name, status);
1367
Oliver Neukum2d20a262011-08-30 15:52:18 +02001368 if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) &&
1369 test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg314b2382011-04-27 10:29:57 -04001370 mgmt_discovering(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001371
Johan Hedberg23bb5762010-12-21 23:01:27 +02001372 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001373
1374 hci_conn_check_pending(hdev);
1375}
1376
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1378{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001379 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001380 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 int num_rsp = *((__u8 *) skb->data);
1382
1383 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1384
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001385 if (!num_rsp)
1386 return;
1387
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001389
Johan Hedberg314b2382011-04-27 10:29:57 -04001390 if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) {
1391
1392 if (test_bit(HCI_MGMT, &hdev->flags))
1393 mgmt_discovering(hdev->id, 1);
1394 }
1395
Johan Hedberge17acd42011-03-30 23:57:16 +03001396 for (; num_rsp; num_rsp--, info++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 bacpy(&data.bdaddr, &info->bdaddr);
1398 data.pscan_rep_mode = info->pscan_rep_mode;
1399 data.pscan_period_mode = info->pscan_period_mode;
1400 data.pscan_mode = info->pscan_mode;
1401 memcpy(data.dev_class, info->dev_class, 3);
1402 data.clock_offset = info->clock_offset;
1403 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001404 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 hci_inquiry_cache_update(hdev, &data);
Johan Hedberge17acd42011-03-30 23:57:16 +03001406 mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class, 0,
1407 NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001409
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410 hci_dev_unlock(hdev);
1411}
1412
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001413static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001415 struct hci_ev_conn_complete *ev = (void *) skb->data;
1416 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001418 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001419
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001421
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001422 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001423 if (!conn) {
1424 if (ev->link_type != SCO_LINK)
1425 goto unlock;
1426
1427 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1428 if (!conn)
1429 goto unlock;
1430
1431 conn->type = SCO_LINK;
1432 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001433
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001434 if (!ev->status) {
1435 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001436
1437 if (conn->type == ACL_LINK) {
1438 conn->state = BT_CONFIG;
1439 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001440 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Vinicius Costa Gomescfafccf2011-08-19 21:06:56 -03001441 mgmt_connected(hdev->id, &ev->bdaddr, conn->type);
Marcel Holtmann769be972008-07-14 20:13:49 +02001442 } else
1443 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001444
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001445 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001446 hci_conn_add_sysfs(conn);
1447
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001448 if (test_bit(HCI_AUTH, &hdev->flags))
1449 conn->link_mode |= HCI_LM_AUTH;
1450
1451 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1452 conn->link_mode |= HCI_LM_ENCRYPT;
1453
1454 /* Get remote features */
1455 if (conn->type == ACL_LINK) {
1456 struct hci_cp_read_remote_features cp;
1457 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001458 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1459 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001460 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001461
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001462 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +02001463 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001464 struct hci_cp_change_conn_ptype cp;
1465 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001466 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1467 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1468 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001469 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001470 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001471 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001472 if (conn->type == ACL_LINK)
1473 mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status);
1474 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001475
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001476 if (conn->type == ACL_LINK)
1477 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001478
Marcel Holtmann769be972008-07-14 20:13:49 +02001479 if (ev->status) {
1480 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001481 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001482 } else if (ev->link_type != ACL_LINK)
1483 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001484
1485unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001487
1488 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489}
1490
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1492{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001493 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 int mask = hdev->link_mode;
1495
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001496 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1497 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498
1499 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1500
Szymon Janc138d22e2011-02-17 16:44:23 +01001501 if ((mask & HCI_LM_ACCEPT) &&
1502 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001504 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506
1507 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001508
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001509 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1510 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001511 memcpy(ie->data.dev_class, ev->dev_class, 3);
1512
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1514 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001515 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1516 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001517 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 hci_dev_unlock(hdev);
1519 return;
1520 }
1521 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001522
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 memcpy(conn->dev_class, ev->dev_class, 3);
1524 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001525
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 hci_dev_unlock(hdev);
1527
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001528 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1529 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001531 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001533 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1534 cp.role = 0x00; /* Become master */
1535 else
1536 cp.role = 0x01; /* Remain slave */
1537
1538 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1539 sizeof(cp), &cp);
1540 } else {
1541 struct hci_cp_accept_sync_conn_req cp;
1542
1543 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001544 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001545
1546 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1547 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1548 cp.max_latency = cpu_to_le16(0xffff);
1549 cp.content_format = cpu_to_le16(hdev->voice_setting);
1550 cp.retrans_effort = 0xff;
1551
1552 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1553 sizeof(cp), &cp);
1554 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555 } else {
1556 /* Connection rejected */
1557 struct hci_cp_reject_conn_req cp;
1558
1559 bacpy(&cp.bdaddr, &ev->bdaddr);
1560 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001561 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 }
1563}
1564
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1566{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001567 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001568 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569
1570 BT_DBG("%s status %d", hdev->name, ev->status);
1571
Johan Hedberg8962ee72011-01-20 12:40:27 +02001572 if (ev->status) {
1573 mgmt_disconnect_failed(hdev->id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 return;
Johan Hedberg8962ee72011-01-20 12:40:27 +02001575 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576
1577 hci_dev_lock(hdev);
1578
Marcel Holtmann04837f62006-07-03 10:02:33 +02001579 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001580 if (!conn)
1581 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001582
Johan Hedbergf7520542011-01-20 12:34:39 +02001583 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03001585 if (conn->type == ACL_LINK || conn->type == LE_LINK)
Johan Hedbergf7520542011-01-20 12:34:39 +02001586 mgmt_disconnected(hdev->id, &conn->dst);
1587
1588 hci_proto_disconn_cfm(conn, ev->reason);
1589 hci_conn_del(conn);
1590
1591unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592 hci_dev_unlock(hdev);
1593}
1594
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001595static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1596{
1597 struct hci_ev_auth_complete *ev = (void *) skb->data;
1598 struct hci_conn *conn;
1599
1600 BT_DBG("%s status %d", hdev->name, ev->status);
1601
1602 hci_dev_lock(hdev);
1603
1604 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001605 if (!conn)
1606 goto unlock;
1607
1608 if (!ev->status) {
1609 if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) &&
1610 test_bit(HCI_CONN_REAUTH_PEND, &conn->pend)) {
1611 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001612 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001613 conn->link_mode |= HCI_LM_AUTH;
1614 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001615 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001616 } else {
1617 mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
1618 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001619
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001620 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1621 clear_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001622
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001623 if (conn->state == BT_CONFIG) {
1624 if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) {
1625 struct hci_cp_set_conn_encrypt cp;
1626 cp.handle = ev->handle;
1627 cp.encrypt = 0x01;
1628 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1629 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001630 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001631 conn->state = BT_CONNECTED;
1632 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001633 hci_conn_put(conn);
1634 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001635 } else {
1636 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001637
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001638 hci_conn_hold(conn);
1639 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1640 hci_conn_put(conn);
1641 }
1642
1643 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1644 if (!ev->status) {
1645 struct hci_cp_set_conn_encrypt cp;
1646 cp.handle = ev->handle;
1647 cp.encrypt = 0x01;
1648 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1649 &cp);
1650 } else {
1651 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1652 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001653 }
1654 }
1655
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001656unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001657 hci_dev_unlock(hdev);
1658}
1659
1660static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1661{
Johan Hedberg127178d2010-11-18 22:22:29 +02001662 struct hci_ev_remote_name *ev = (void *) skb->data;
1663 struct hci_conn *conn;
1664
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001665 BT_DBG("%s", hdev->name);
1666
1667 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001668
1669 hci_dev_lock(hdev);
1670
Johan Hedberga88a9652011-03-30 13:18:12 +03001671 if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags))
1672 mgmt_remote_name(hdev->id, &ev->bdaddr, ev->name);
1673
Johan Hedberg127178d2010-11-18 22:22:29 +02001674 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001675 if (!conn)
1676 goto unlock;
1677
1678 if (!hci_outgoing_auth_needed(hdev, conn))
1679 goto unlock;
1680
1681 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001682 struct hci_cp_auth_requested cp;
1683 cp.handle = __cpu_to_le16(conn->handle);
1684 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1685 }
1686
Johan Hedberg79c6c702011-04-28 11:28:55 -07001687unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001688 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001689}
1690
1691static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1692{
1693 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1694 struct hci_conn *conn;
1695
1696 BT_DBG("%s status %d", hdev->name, ev->status);
1697
1698 hci_dev_lock(hdev);
1699
1700 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1701 if (conn) {
1702 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001703 if (ev->encrypt) {
1704 /* Encryption implies authentication */
1705 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001706 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001707 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001708 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001709 conn->link_mode &= ~HCI_LM_ENCRYPT;
1710 }
1711
1712 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1713
Marcel Holtmannf8558552008-07-14 20:13:49 +02001714 if (conn->state == BT_CONFIG) {
1715 if (!ev->status)
1716 conn->state = BT_CONNECTED;
1717
1718 hci_proto_connect_cfm(conn, ev->status);
1719 hci_conn_put(conn);
1720 } else
1721 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001722 }
1723
1724 hci_dev_unlock(hdev);
1725}
1726
1727static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1728{
1729 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1730 struct hci_conn *conn;
1731
1732 BT_DBG("%s status %d", hdev->name, ev->status);
1733
1734 hci_dev_lock(hdev);
1735
1736 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1737 if (conn) {
1738 if (!ev->status)
1739 conn->link_mode |= HCI_LM_SECURE;
1740
1741 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1742
1743 hci_key_change_cfm(conn, ev->status);
1744 }
1745
1746 hci_dev_unlock(hdev);
1747}
1748
1749static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1750{
1751 struct hci_ev_remote_features *ev = (void *) skb->data;
1752 struct hci_conn *conn;
1753
1754 BT_DBG("%s status %d", hdev->name, ev->status);
1755
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001756 hci_dev_lock(hdev);
1757
1758 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001759 if (!conn)
1760 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001761
Johan Hedbergccd556f2010-11-10 17:11:51 +02001762 if (!ev->status)
1763 memcpy(conn->features, ev->features, 8);
1764
1765 if (conn->state != BT_CONFIG)
1766 goto unlock;
1767
1768 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1769 struct hci_cp_read_remote_ext_features cp;
1770 cp.handle = ev->handle;
1771 cp.page = 0x01;
1772 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001773 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001774 goto unlock;
1775 }
1776
Johan Hedberg127178d2010-11-18 22:22:29 +02001777 if (!ev->status) {
1778 struct hci_cp_remote_name_req cp;
1779 memset(&cp, 0, sizeof(cp));
1780 bacpy(&cp.bdaddr, &conn->dst);
1781 cp.pscan_rep_mode = 0x02;
1782 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1783 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001784
Johan Hedberg127178d2010-11-18 22:22:29 +02001785 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001786 conn->state = BT_CONNECTED;
1787 hci_proto_connect_cfm(conn, ev->status);
1788 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001789 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001790
Johan Hedbergccd556f2010-11-10 17:11:51 +02001791unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001792 hci_dev_unlock(hdev);
1793}
1794
1795static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1796{
1797 BT_DBG("%s", hdev->name);
1798}
1799
1800static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1801{
1802 BT_DBG("%s", hdev->name);
1803}
1804
1805static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1806{
1807 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1808 __u16 opcode;
1809
1810 skb_pull(skb, sizeof(*ev));
1811
1812 opcode = __le16_to_cpu(ev->opcode);
1813
1814 switch (opcode) {
1815 case HCI_OP_INQUIRY_CANCEL:
1816 hci_cc_inquiry_cancel(hdev, skb);
1817 break;
1818
1819 case HCI_OP_EXIT_PERIODIC_INQ:
1820 hci_cc_exit_periodic_inq(hdev, skb);
1821 break;
1822
1823 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1824 hci_cc_remote_name_req_cancel(hdev, skb);
1825 break;
1826
1827 case HCI_OP_ROLE_DISCOVERY:
1828 hci_cc_role_discovery(hdev, skb);
1829 break;
1830
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001831 case HCI_OP_READ_LINK_POLICY:
1832 hci_cc_read_link_policy(hdev, skb);
1833 break;
1834
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001835 case HCI_OP_WRITE_LINK_POLICY:
1836 hci_cc_write_link_policy(hdev, skb);
1837 break;
1838
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001839 case HCI_OP_READ_DEF_LINK_POLICY:
1840 hci_cc_read_def_link_policy(hdev, skb);
1841 break;
1842
1843 case HCI_OP_WRITE_DEF_LINK_POLICY:
1844 hci_cc_write_def_link_policy(hdev, skb);
1845 break;
1846
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001847 case HCI_OP_RESET:
1848 hci_cc_reset(hdev, skb);
1849 break;
1850
1851 case HCI_OP_WRITE_LOCAL_NAME:
1852 hci_cc_write_local_name(hdev, skb);
1853 break;
1854
1855 case HCI_OP_READ_LOCAL_NAME:
1856 hci_cc_read_local_name(hdev, skb);
1857 break;
1858
1859 case HCI_OP_WRITE_AUTH_ENABLE:
1860 hci_cc_write_auth_enable(hdev, skb);
1861 break;
1862
1863 case HCI_OP_WRITE_ENCRYPT_MODE:
1864 hci_cc_write_encrypt_mode(hdev, skb);
1865 break;
1866
1867 case HCI_OP_WRITE_SCAN_ENABLE:
1868 hci_cc_write_scan_enable(hdev, skb);
1869 break;
1870
1871 case HCI_OP_READ_CLASS_OF_DEV:
1872 hci_cc_read_class_of_dev(hdev, skb);
1873 break;
1874
1875 case HCI_OP_WRITE_CLASS_OF_DEV:
1876 hci_cc_write_class_of_dev(hdev, skb);
1877 break;
1878
1879 case HCI_OP_READ_VOICE_SETTING:
1880 hci_cc_read_voice_setting(hdev, skb);
1881 break;
1882
1883 case HCI_OP_WRITE_VOICE_SETTING:
1884 hci_cc_write_voice_setting(hdev, skb);
1885 break;
1886
1887 case HCI_OP_HOST_BUFFER_SIZE:
1888 hci_cc_host_buffer_size(hdev, skb);
1889 break;
1890
Marcel Holtmann333140b2008-07-14 20:13:48 +02001891 case HCI_OP_READ_SSP_MODE:
1892 hci_cc_read_ssp_mode(hdev, skb);
1893 break;
1894
1895 case HCI_OP_WRITE_SSP_MODE:
1896 hci_cc_write_ssp_mode(hdev, skb);
1897 break;
1898
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001899 case HCI_OP_READ_LOCAL_VERSION:
1900 hci_cc_read_local_version(hdev, skb);
1901 break;
1902
1903 case HCI_OP_READ_LOCAL_COMMANDS:
1904 hci_cc_read_local_commands(hdev, skb);
1905 break;
1906
1907 case HCI_OP_READ_LOCAL_FEATURES:
1908 hci_cc_read_local_features(hdev, skb);
1909 break;
1910
Andre Guedes971e3a42011-06-30 19:20:52 -03001911 case HCI_OP_READ_LOCAL_EXT_FEATURES:
1912 hci_cc_read_local_ext_features(hdev, skb);
1913 break;
1914
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001915 case HCI_OP_READ_BUFFER_SIZE:
1916 hci_cc_read_buffer_size(hdev, skb);
1917 break;
1918
1919 case HCI_OP_READ_BD_ADDR:
1920 hci_cc_read_bd_addr(hdev, skb);
1921 break;
1922
Johan Hedberg23bb5762010-12-21 23:01:27 +02001923 case HCI_OP_WRITE_CA_TIMEOUT:
1924 hci_cc_write_ca_timeout(hdev, skb);
1925 break;
1926
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03001927 case HCI_OP_READ_LOCAL_AMP_INFO:
1928 hci_cc_read_local_amp_info(hdev, skb);
1929 break;
1930
Johan Hedbergb0916ea2011-01-10 13:44:55 +02001931 case HCI_OP_DELETE_STORED_LINK_KEY:
1932 hci_cc_delete_stored_link_key(hdev, skb);
1933 break;
1934
Johan Hedbergd5859e22011-01-25 01:19:58 +02001935 case HCI_OP_SET_EVENT_MASK:
1936 hci_cc_set_event_mask(hdev, skb);
1937 break;
1938
1939 case HCI_OP_WRITE_INQUIRY_MODE:
1940 hci_cc_write_inquiry_mode(hdev, skb);
1941 break;
1942
1943 case HCI_OP_READ_INQ_RSP_TX_POWER:
1944 hci_cc_read_inq_rsp_tx_power(hdev, skb);
1945 break;
1946
1947 case HCI_OP_SET_EVENT_FLT:
1948 hci_cc_set_event_flt(hdev, skb);
1949 break;
1950
Johan Hedberg980e1a52011-01-22 06:10:07 +02001951 case HCI_OP_PIN_CODE_REPLY:
1952 hci_cc_pin_code_reply(hdev, skb);
1953 break;
1954
1955 case HCI_OP_PIN_CODE_NEG_REPLY:
1956 hci_cc_pin_code_neg_reply(hdev, skb);
1957 break;
1958
Szymon Jancc35938b2011-03-22 13:12:21 +01001959 case HCI_OP_READ_LOCAL_OOB_DATA:
1960 hci_cc_read_local_oob_data_reply(hdev, skb);
1961 break;
1962
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001963 case HCI_OP_LE_READ_BUFFER_SIZE:
1964 hci_cc_le_read_buffer_size(hdev, skb);
1965 break;
1966
Johan Hedberga5c29682011-02-19 12:05:57 -03001967 case HCI_OP_USER_CONFIRM_REPLY:
1968 hci_cc_user_confirm_reply(hdev, skb);
1969 break;
1970
1971 case HCI_OP_USER_CONFIRM_NEG_REPLY:
1972 hci_cc_user_confirm_neg_reply(hdev, skb);
1973 break;
1974
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001975 case HCI_OP_LE_SET_SCAN_ENABLE:
1976 hci_cc_le_set_scan_enable(hdev, skb);
1977 break;
1978
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001979 case HCI_OP_LE_LTK_REPLY:
1980 hci_cc_le_ltk_reply(hdev, skb);
1981 break;
1982
1983 case HCI_OP_LE_LTK_NEG_REPLY:
1984 hci_cc_le_ltk_neg_reply(hdev, skb);
1985 break;
1986
Andre Guedesf9b49302011-06-30 19:20:53 -03001987 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
1988 hci_cc_write_le_host_supported(hdev, skb);
1989 break;
1990
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001991 default:
1992 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1993 break;
1994 }
1995
Ville Tervo6bd32322011-02-16 16:32:41 +02001996 if (ev->opcode != HCI_OP_NOP)
1997 del_timer(&hdev->cmd_timer);
1998
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001999 if (ev->ncmd) {
2000 atomic_set(&hdev->cmd_cnt, 1);
2001 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002002 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002003 }
2004}
2005
2006static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2007{
2008 struct hci_ev_cmd_status *ev = (void *) skb->data;
2009 __u16 opcode;
2010
2011 skb_pull(skb, sizeof(*ev));
2012
2013 opcode = __le16_to_cpu(ev->opcode);
2014
2015 switch (opcode) {
2016 case HCI_OP_INQUIRY:
2017 hci_cs_inquiry(hdev, ev->status);
2018 break;
2019
2020 case HCI_OP_CREATE_CONN:
2021 hci_cs_create_conn(hdev, ev->status);
2022 break;
2023
2024 case HCI_OP_ADD_SCO:
2025 hci_cs_add_sco(hdev, ev->status);
2026 break;
2027
Marcel Holtmannf8558552008-07-14 20:13:49 +02002028 case HCI_OP_AUTH_REQUESTED:
2029 hci_cs_auth_requested(hdev, ev->status);
2030 break;
2031
2032 case HCI_OP_SET_CONN_ENCRYPT:
2033 hci_cs_set_conn_encrypt(hdev, ev->status);
2034 break;
2035
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002036 case HCI_OP_REMOTE_NAME_REQ:
2037 hci_cs_remote_name_req(hdev, ev->status);
2038 break;
2039
Marcel Holtmann769be972008-07-14 20:13:49 +02002040 case HCI_OP_READ_REMOTE_FEATURES:
2041 hci_cs_read_remote_features(hdev, ev->status);
2042 break;
2043
2044 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2045 hci_cs_read_remote_ext_features(hdev, ev->status);
2046 break;
2047
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002048 case HCI_OP_SETUP_SYNC_CONN:
2049 hci_cs_setup_sync_conn(hdev, ev->status);
2050 break;
2051
2052 case HCI_OP_SNIFF_MODE:
2053 hci_cs_sniff_mode(hdev, ev->status);
2054 break;
2055
2056 case HCI_OP_EXIT_SNIFF_MODE:
2057 hci_cs_exit_sniff_mode(hdev, ev->status);
2058 break;
2059
Johan Hedberg8962ee72011-01-20 12:40:27 +02002060 case HCI_OP_DISCONNECT:
2061 if (ev->status != 0)
2062 mgmt_disconnect_failed(hdev->id);
2063 break;
2064
Ville Tervofcd89c02011-02-10 22:38:47 -03002065 case HCI_OP_LE_CREATE_CONN:
2066 hci_cs_le_create_conn(hdev, ev->status);
2067 break;
2068
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002069 case HCI_OP_LE_START_ENC:
2070 hci_cs_le_start_enc(hdev, ev->status);
2071 break;
2072
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002073 default:
2074 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2075 break;
2076 }
2077
Ville Tervo6bd32322011-02-16 16:32:41 +02002078 if (ev->opcode != HCI_OP_NOP)
2079 del_timer(&hdev->cmd_timer);
2080
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002081 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002082 atomic_set(&hdev->cmd_cnt, 1);
2083 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002084 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002085 }
2086}
2087
2088static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2089{
2090 struct hci_ev_role_change *ev = (void *) skb->data;
2091 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_ba(hdev, ACL_LINK, &ev->bdaddr);
2098 if (conn) {
2099 if (!ev->status) {
2100 if (ev->role)
2101 conn->link_mode &= ~HCI_LM_MASTER;
2102 else
2103 conn->link_mode |= HCI_LM_MASTER;
2104 }
2105
2106 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
2107
2108 hci_role_switch_cfm(conn, ev->status, ev->role);
2109 }
2110
2111 hci_dev_unlock(hdev);
2112}
2113
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2115{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002116 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002117 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118 int i;
2119
2120 skb_pull(skb, sizeof(*ev));
2121
2122 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2123
2124 if (skb->len < ev->num_hndl * 4) {
2125 BT_DBG("%s bad parameters", hdev->name);
2126 return;
2127 }
2128
2129 tasklet_disable(&hdev->tx_task);
2130
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002131 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002132 struct hci_conn *conn;
2133 __u16 handle, count;
2134
Harvey Harrison83985312008-05-02 16:25:46 -07002135 handle = get_unaligned_le16(ptr++);
2136 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137
2138 conn = hci_conn_hash_lookup_handle(hdev, handle);
2139 if (conn) {
2140 conn->sent -= count;
2141
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002142 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002143 hdev->acl_cnt += count;
2144 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145 hdev->acl_cnt = hdev->acl_pkts;
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002146 } else if (conn->type == LE_LINK) {
2147 if (hdev->le_pkts) {
2148 hdev->le_cnt += count;
2149 if (hdev->le_cnt > hdev->le_pkts)
2150 hdev->le_cnt = hdev->le_pkts;
2151 } else {
2152 hdev->acl_cnt += count;
2153 if (hdev->acl_cnt > hdev->acl_pkts)
2154 hdev->acl_cnt = hdev->acl_pkts;
2155 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002156 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002157 hdev->sco_cnt += count;
2158 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002159 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002160 }
2161 }
2162 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002163
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002164 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002165
2166 tasklet_enable(&hdev->tx_task);
2167}
2168
Marcel Holtmann04837f62006-07-03 10:02:33 +02002169static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002171 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002172 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002173
2174 BT_DBG("%s status %d", hdev->name, ev->status);
2175
2176 hci_dev_lock(hdev);
2177
Marcel Holtmann04837f62006-07-03 10:02:33 +02002178 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2179 if (conn) {
2180 conn->mode = ev->mode;
2181 conn->interval = __le16_to_cpu(ev->interval);
2182
2183 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
2184 if (conn->mode == HCI_CM_ACTIVE)
2185 conn->power_save = 1;
2186 else
2187 conn->power_save = 0;
2188 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002189
2190 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
2191 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002192 }
2193
2194 hci_dev_unlock(hdev);
2195}
2196
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2198{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002199 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2200 struct hci_conn *conn;
2201
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002202 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002203
2204 hci_dev_lock(hdev);
2205
2206 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002207 if (!conn)
2208 goto unlock;
2209
2210 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002211 hci_conn_hold(conn);
2212 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2213 hci_conn_put(conn);
2214 }
2215
Johan Hedberg03b555e2011-01-04 15:40:05 +02002216 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
2217 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2218 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg582fbe92011-04-28 11:28:58 -07002219 else if (test_bit(HCI_MGMT, &hdev->flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002220 u8 secure;
2221
2222 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2223 secure = 1;
2224 else
2225 secure = 0;
2226
2227 mgmt_pin_code_request(hdev->id, &ev->bdaddr, secure);
2228 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002229
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002230unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002231 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002232}
2233
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2235{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002236 struct hci_ev_link_key_req *ev = (void *) skb->data;
2237 struct hci_cp_link_key_reply cp;
2238 struct hci_conn *conn;
2239 struct link_key *key;
2240
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002241 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002242
2243 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
2244 return;
2245
2246 hci_dev_lock(hdev);
2247
2248 key = hci_find_link_key(hdev, &ev->bdaddr);
2249 if (!key) {
2250 BT_DBG("%s link key not found for %s", hdev->name,
2251 batostr(&ev->bdaddr));
2252 goto not_found;
2253 }
2254
2255 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2256 batostr(&ev->bdaddr));
2257
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002258 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) &&
2259 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002260 BT_DBG("%s ignoring debug key", hdev->name);
2261 goto not_found;
2262 }
2263
2264 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002265 if (conn) {
2266 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2267 conn->auth_type != 0xff &&
2268 (conn->auth_type & 0x01)) {
2269 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2270 goto not_found;
2271 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002272
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002273 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2274 conn->pending_sec_level == BT_SECURITY_HIGH) {
2275 BT_DBG("%s ignoring key unauthenticated for high \
2276 security", hdev->name);
2277 goto not_found;
2278 }
2279
2280 conn->key_type = key->type;
2281 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002282 }
2283
2284 bacpy(&cp.bdaddr, &ev->bdaddr);
2285 memcpy(cp.link_key, key->val, 16);
2286
2287 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2288
2289 hci_dev_unlock(hdev);
2290
2291 return;
2292
2293not_found:
2294 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2295 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296}
2297
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2299{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002300 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2301 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002302 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002303
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002304 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002305
2306 hci_dev_lock(hdev);
2307
2308 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2309 if (conn) {
2310 hci_conn_hold(conn);
2311 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002312 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002313
2314 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2315 conn->key_type = ev->key_type;
2316
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002317 hci_conn_put(conn);
2318 }
2319
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002320 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002321 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002322 ev->key_type, pin_len);
2323
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002324 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325}
2326
Marcel Holtmann04837f62006-07-03 10:02:33 +02002327static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2328{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002329 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002330 struct hci_conn *conn;
2331
2332 BT_DBG("%s status %d", hdev->name, ev->status);
2333
2334 hci_dev_lock(hdev);
2335
2336 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337 if (conn && !ev->status) {
2338 struct inquiry_entry *ie;
2339
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002340 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2341 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342 ie->data.clock_offset = ev->clock_offset;
2343 ie->timestamp = jiffies;
2344 }
2345 }
2346
2347 hci_dev_unlock(hdev);
2348}
2349
Marcel Holtmanna8746412008-07-14 20:13:46 +02002350static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2351{
2352 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2353 struct hci_conn *conn;
2354
2355 BT_DBG("%s status %d", hdev->name, ev->status);
2356
2357 hci_dev_lock(hdev);
2358
2359 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2360 if (conn && !ev->status)
2361 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2362
2363 hci_dev_unlock(hdev);
2364}
2365
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002366static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2367{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002368 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002369 struct inquiry_entry *ie;
2370
2371 BT_DBG("%s", hdev->name);
2372
2373 hci_dev_lock(hdev);
2374
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002375 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2376 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002377 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2378 ie->timestamp = jiffies;
2379 }
2380
2381 hci_dev_unlock(hdev);
2382}
2383
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002384static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2385{
2386 struct inquiry_data data;
2387 int num_rsp = *((__u8 *) skb->data);
2388
2389 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2390
2391 if (!num_rsp)
2392 return;
2393
2394 hci_dev_lock(hdev);
2395
Johan Hedberg314b2382011-04-27 10:29:57 -04002396 if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) {
2397
2398 if (test_bit(HCI_MGMT, &hdev->flags))
2399 mgmt_discovering(hdev->id, 1);
2400 }
2401
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002402 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002403 struct inquiry_info_with_rssi_and_pscan_mode *info;
2404 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002405
Johan Hedberge17acd42011-03-30 23:57:16 +03002406 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002407 bacpy(&data.bdaddr, &info->bdaddr);
2408 data.pscan_rep_mode = info->pscan_rep_mode;
2409 data.pscan_period_mode = info->pscan_period_mode;
2410 data.pscan_mode = info->pscan_mode;
2411 memcpy(data.dev_class, info->dev_class, 3);
2412 data.clock_offset = info->clock_offset;
2413 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002414 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002415 hci_inquiry_cache_update(hdev, &data);
Johan Hedberge17acd42011-03-30 23:57:16 +03002416 mgmt_device_found(hdev->id, &info->bdaddr,
2417 info->dev_class, info->rssi,
2418 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002419 }
2420 } else {
2421 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2422
Johan Hedberge17acd42011-03-30 23:57:16 +03002423 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002424 bacpy(&data.bdaddr, &info->bdaddr);
2425 data.pscan_rep_mode = info->pscan_rep_mode;
2426 data.pscan_period_mode = info->pscan_period_mode;
2427 data.pscan_mode = 0x00;
2428 memcpy(data.dev_class, info->dev_class, 3);
2429 data.clock_offset = info->clock_offset;
2430 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002431 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002432 hci_inquiry_cache_update(hdev, &data);
Johan Hedberge17acd42011-03-30 23:57:16 +03002433 mgmt_device_found(hdev->id, &info->bdaddr,
2434 info->dev_class, info->rssi,
2435 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002436 }
2437 }
2438
2439 hci_dev_unlock(hdev);
2440}
2441
2442static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2443{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002444 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2445 struct hci_conn *conn;
2446
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002447 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002448
Marcel Holtmann41a96212008-07-14 20:13:48 +02002449 hci_dev_lock(hdev);
2450
2451 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002452 if (!conn)
2453 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002454
Johan Hedbergccd556f2010-11-10 17:11:51 +02002455 if (!ev->status && ev->page == 0x01) {
2456 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002457
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002458 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2459 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002460 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002461
Johan Hedbergccd556f2010-11-10 17:11:51 +02002462 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002463 }
2464
Johan Hedbergccd556f2010-11-10 17:11:51 +02002465 if (conn->state != BT_CONFIG)
2466 goto unlock;
2467
Johan Hedberg127178d2010-11-18 22:22:29 +02002468 if (!ev->status) {
2469 struct hci_cp_remote_name_req cp;
2470 memset(&cp, 0, sizeof(cp));
2471 bacpy(&cp.bdaddr, &conn->dst);
2472 cp.pscan_rep_mode = 0x02;
2473 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2474 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002475
Johan Hedberg127178d2010-11-18 22:22:29 +02002476 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002477 conn->state = BT_CONNECTED;
2478 hci_proto_connect_cfm(conn, ev->status);
2479 hci_conn_put(conn);
2480 }
2481
2482unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002483 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002484}
2485
2486static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2487{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002488 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2489 struct hci_conn *conn;
2490
2491 BT_DBG("%s status %d", hdev->name, ev->status);
2492
2493 hci_dev_lock(hdev);
2494
2495 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002496 if (!conn) {
2497 if (ev->link_type == ESCO_LINK)
2498 goto unlock;
2499
2500 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2501 if (!conn)
2502 goto unlock;
2503
2504 conn->type = SCO_LINK;
2505 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002506
Marcel Holtmann732547f2009-04-19 19:14:14 +02002507 switch (ev->status) {
2508 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002509 conn->handle = __le16_to_cpu(ev->handle);
2510 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002511
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002512 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002513 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002514 break;
2515
Stephen Coe705e5712010-02-16 11:29:44 -05002516 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002517 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002518 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002519 case 0x1f: /* Unspecified error */
2520 if (conn->out && conn->attempt < 2) {
2521 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2522 (hdev->esco_type & EDR_ESCO_MASK);
2523 hci_setup_sync(conn, conn->link->handle);
2524 goto unlock;
2525 }
2526 /* fall through */
2527
2528 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002529 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002530 break;
2531 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002532
2533 hci_proto_connect_cfm(conn, ev->status);
2534 if (ev->status)
2535 hci_conn_del(conn);
2536
2537unlock:
2538 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002539}
2540
2541static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2542{
2543 BT_DBG("%s", hdev->name);
2544}
2545
Marcel Holtmann04837f62006-07-03 10:02:33 +02002546static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2547{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002548 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002549
2550 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002551}
2552
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002553static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2554{
2555 struct inquiry_data data;
2556 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2557 int num_rsp = *((__u8 *) skb->data);
2558
2559 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2560
2561 if (!num_rsp)
2562 return;
2563
Johan Hedberg314b2382011-04-27 10:29:57 -04002564 if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) {
2565
2566 if (test_bit(HCI_MGMT, &hdev->flags))
2567 mgmt_discovering(hdev->id, 1);
2568 }
2569
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002570 hci_dev_lock(hdev);
2571
Johan Hedberge17acd42011-03-30 23:57:16 +03002572 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002573 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002574 data.pscan_rep_mode = info->pscan_rep_mode;
2575 data.pscan_period_mode = info->pscan_period_mode;
2576 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002577 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002578 data.clock_offset = info->clock_offset;
2579 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002580 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002581 hci_inquiry_cache_update(hdev, &data);
Johan Hedberge17acd42011-03-30 23:57:16 +03002582 mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class,
2583 info->rssi, info->data);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002584 }
2585
2586 hci_dev_unlock(hdev);
2587}
2588
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002589static inline u8 hci_get_auth_req(struct hci_conn *conn)
2590{
2591 /* If remote requests dedicated bonding follow that lead */
2592 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2593 /* If both remote and local IO capabilities allow MITM
2594 * protection then require it, otherwise don't */
2595 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2596 return 0x02;
2597 else
2598 return 0x03;
2599 }
2600
2601 /* If remote requests no-bonding follow that lead */
2602 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002603 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002604
2605 return conn->auth_type;
2606}
2607
Marcel Holtmann04936842008-07-14 20:13:48 +02002608static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2609{
2610 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2611 struct hci_conn *conn;
2612
2613 BT_DBG("%s", hdev->name);
2614
2615 hci_dev_lock(hdev);
2616
2617 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002618 if (!conn)
2619 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002620
Johan Hedberg03b555e2011-01-04 15:40:05 +02002621 hci_conn_hold(conn);
2622
2623 if (!test_bit(HCI_MGMT, &hdev->flags))
2624 goto unlock;
2625
2626 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
2627 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002628 struct hci_cp_io_capability_reply cp;
2629
2630 bacpy(&cp.bdaddr, &ev->bdaddr);
2631 cp.capability = conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07002632 conn->auth_type = hci_get_auth_req(conn);
2633 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002634
Szymon Jancce85ee12011-03-22 13:12:23 +01002635 if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
2636 hci_find_remote_oob_data(hdev, &conn->dst))
2637 cp.oob_data = 0x01;
2638 else
2639 cp.oob_data = 0x00;
2640
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002641 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2642 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002643 } else {
2644 struct hci_cp_io_capability_neg_reply cp;
2645
2646 bacpy(&cp.bdaddr, &ev->bdaddr);
Johan Hedbergbe771592011-04-28 11:28:57 -07002647 cp.reason = 0x18; /* Pairing not allowed */
Johan Hedberg03b555e2011-01-04 15:40:05 +02002648
2649 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2650 sizeof(cp), &cp);
2651 }
2652
2653unlock:
2654 hci_dev_unlock(hdev);
2655}
2656
2657static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2658{
2659 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2660 struct hci_conn *conn;
2661
2662 BT_DBG("%s", hdev->name);
2663
2664 hci_dev_lock(hdev);
2665
2666 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2667 if (!conn)
2668 goto unlock;
2669
Johan Hedberg03b555e2011-01-04 15:40:05 +02002670 conn->remote_cap = ev->capability;
2671 conn->remote_oob = ev->oob_data;
2672 conn->remote_auth = ev->authentication;
2673
2674unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002675 hci_dev_unlock(hdev);
2676}
2677
Johan Hedberga5c29682011-02-19 12:05:57 -03002678static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2679 struct sk_buff *skb)
2680{
2681 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002682 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07002683 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03002684
2685 BT_DBG("%s", hdev->name);
2686
2687 hci_dev_lock(hdev);
2688
Johan Hedberg7a828902011-04-28 11:28:53 -07002689 if (!test_bit(HCI_MGMT, &hdev->flags))
2690 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03002691
Johan Hedberg7a828902011-04-28 11:28:53 -07002692 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2693 if (!conn)
2694 goto unlock;
2695
2696 loc_mitm = (conn->auth_type & 0x01);
2697 rem_mitm = (conn->remote_auth & 0x01);
2698
2699 /* If we require MITM but the remote device can't provide that
2700 * (it has NoInputNoOutput) then reject the confirmation
2701 * request. The only exception is when we're dedicated bonding
2702 * initiators (connect_cfm_cb set) since then we always have the MITM
2703 * bit set. */
2704 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
2705 BT_DBG("Rejecting request: remote device can't provide MITM");
2706 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
2707 sizeof(ev->bdaddr), &ev->bdaddr);
2708 goto unlock;
2709 }
2710
2711 /* If no side requires MITM protection; auto-accept */
2712 if ((!loc_mitm || conn->remote_cap == 0x03) &&
2713 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002714
2715 /* If we're not the initiators request authorization to
2716 * proceed from user space (mgmt_user_confirm with
2717 * confirm_hint set to 1). */
2718 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
2719 BT_DBG("Confirming auto-accept as acceptor");
2720 confirm_hint = 1;
2721 goto confirm;
2722 }
2723
Johan Hedberg9f616562011-04-28 11:28:54 -07002724 BT_DBG("Auto-accept of user confirmation with %ums delay",
2725 hdev->auto_accept_delay);
2726
2727 if (hdev->auto_accept_delay > 0) {
2728 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
2729 mod_timer(&conn->auto_accept_timer, jiffies + delay);
2730 goto unlock;
2731 }
2732
Johan Hedberg7a828902011-04-28 11:28:53 -07002733 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
2734 sizeof(ev->bdaddr), &ev->bdaddr);
2735 goto unlock;
2736 }
2737
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002738confirm:
2739 mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey,
2740 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07002741
2742unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03002743 hci_dev_unlock(hdev);
2744}
2745
Marcel Holtmann04936842008-07-14 20:13:48 +02002746static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2747{
2748 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
2749 struct hci_conn *conn;
2750
2751 BT_DBG("%s", hdev->name);
2752
2753 hci_dev_lock(hdev);
2754
2755 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03002756 if (!conn)
2757 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002758
Johan Hedberg2a611692011-02-19 12:06:00 -03002759 /* To avoid duplicate auth_failed events to user space we check
2760 * the HCI_CONN_AUTH_PEND flag which will be set if we
2761 * initiated the authentication. A traditional auth_complete
2762 * event gets always produced as initiator and is also mapped to
2763 * the mgmt_auth_failed event */
2764 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
2765 mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
2766
2767 hci_conn_put(conn);
2768
2769unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002770 hci_dev_unlock(hdev);
2771}
2772
Marcel Holtmann41a96212008-07-14 20:13:48 +02002773static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2774{
2775 struct hci_ev_remote_host_features *ev = (void *) skb->data;
2776 struct inquiry_entry *ie;
2777
2778 BT_DBG("%s", hdev->name);
2779
2780 hci_dev_lock(hdev);
2781
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002782 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2783 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02002784 ie->data.ssp_mode = (ev->features[0] & 0x01);
2785
2786 hci_dev_unlock(hdev);
2787}
2788
Szymon Janc2763eda2011-03-22 13:12:22 +01002789static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
2790 struct sk_buff *skb)
2791{
2792 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
2793 struct oob_data *data;
2794
2795 BT_DBG("%s", hdev->name);
2796
2797 hci_dev_lock(hdev);
2798
Szymon Jance1ba1f12011-04-06 13:01:59 +02002799 if (!test_bit(HCI_MGMT, &hdev->flags))
2800 goto unlock;
2801
Szymon Janc2763eda2011-03-22 13:12:22 +01002802 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
2803 if (data) {
2804 struct hci_cp_remote_oob_data_reply cp;
2805
2806 bacpy(&cp.bdaddr, &ev->bdaddr);
2807 memcpy(cp.hash, data->hash, sizeof(cp.hash));
2808 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
2809
2810 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
2811 &cp);
2812 } else {
2813 struct hci_cp_remote_oob_data_neg_reply cp;
2814
2815 bacpy(&cp.bdaddr, &ev->bdaddr);
2816 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
2817 &cp);
2818 }
2819
Szymon Jance1ba1f12011-04-06 13:01:59 +02002820unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01002821 hci_dev_unlock(hdev);
2822}
2823
Ville Tervofcd89c02011-02-10 22:38:47 -03002824static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2825{
2826 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2827 struct hci_conn *conn;
2828
2829 BT_DBG("%s status %d", hdev->name, ev->status);
2830
2831 hci_dev_lock(hdev);
2832
2833 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03002834 if (!conn) {
2835 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
2836 if (!conn) {
2837 BT_ERR("No memory for new connection");
2838 hci_dev_unlock(hdev);
2839 return;
2840 }
Andre Guedes29b79882011-05-31 14:20:54 -03002841
2842 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03002843 }
Ville Tervofcd89c02011-02-10 22:38:47 -03002844
2845 if (ev->status) {
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03002846 mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03002847 hci_proto_connect_cfm(conn, ev->status);
2848 conn->state = BT_CLOSED;
2849 hci_conn_del(conn);
2850 goto unlock;
2851 }
2852
Vinicius Costa Gomescfafccf2011-08-19 21:06:56 -03002853 mgmt_connected(hdev->id, &ev->bdaddr, conn->type);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03002854
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03002855 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03002856 conn->handle = __le16_to_cpu(ev->handle);
2857 conn->state = BT_CONNECTED;
2858
2859 hci_conn_hold_device(conn);
2860 hci_conn_add_sysfs(conn);
2861
2862 hci_proto_connect_cfm(conn, ev->status);
2863
2864unlock:
2865 hci_dev_unlock(hdev);
2866}
2867
Andre Guedes9aa04c92011-05-26 16:23:51 -03002868static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
2869 struct sk_buff *skb)
2870{
Andre Guedese95beb42011-09-26 20:48:35 -03002871 u8 num_reports = skb->data[0];
2872 void *ptr = &skb->data[1];
Andre Guedes9aa04c92011-05-26 16:23:51 -03002873
2874 hci_dev_lock(hdev);
2875
Andre Guedese95beb42011-09-26 20:48:35 -03002876 while (num_reports--) {
2877 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03002878
Andre Guedes9aa04c92011-05-26 16:23:51 -03002879 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03002880
2881 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03002882 }
2883
2884 hci_dev_unlock(hdev);
2885}
2886
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002887static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
2888 struct sk_buff *skb)
2889{
2890 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
2891 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002892 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002893 struct hci_conn *conn;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002894 struct link_key *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002895
2896 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
2897
2898 hci_dev_lock(hdev);
2899
2900 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002901 if (conn == NULL)
2902 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002903
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002904 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
2905 if (ltk == NULL)
2906 goto not_found;
2907
2908 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002909 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes726b4ff2011-07-08 18:31:45 -03002910 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002911
2912 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
2913
2914 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002915
2916 return;
2917
2918not_found:
2919 neg.handle = ev->handle;
2920 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
2921 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002922}
2923
Ville Tervofcd89c02011-02-10 22:38:47 -03002924static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
2925{
2926 struct hci_ev_le_meta *le_ev = (void *) skb->data;
2927
2928 skb_pull(skb, sizeof(*le_ev));
2929
2930 switch (le_ev->subevent) {
2931 case HCI_EV_LE_CONN_COMPLETE:
2932 hci_le_conn_complete_evt(hdev, skb);
2933 break;
2934
Andre Guedes9aa04c92011-05-26 16:23:51 -03002935 case HCI_EV_LE_ADVERTISING_REPORT:
2936 hci_le_adv_report_evt(hdev, skb);
2937 break;
2938
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002939 case HCI_EV_LE_LTK_REQ:
2940 hci_le_ltk_request_evt(hdev, skb);
2941 break;
2942
Ville Tervofcd89c02011-02-10 22:38:47 -03002943 default:
2944 break;
2945 }
2946}
2947
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
2949{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002950 struct hci_event_hdr *hdr = (void *) skb->data;
2951 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952
2953 skb_pull(skb, HCI_EVENT_HDR_SIZE);
2954
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002955 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956 case HCI_EV_INQUIRY_COMPLETE:
2957 hci_inquiry_complete_evt(hdev, skb);
2958 break;
2959
2960 case HCI_EV_INQUIRY_RESULT:
2961 hci_inquiry_result_evt(hdev, skb);
2962 break;
2963
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002964 case HCI_EV_CONN_COMPLETE:
2965 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02002966 break;
2967
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968 case HCI_EV_CONN_REQUEST:
2969 hci_conn_request_evt(hdev, skb);
2970 break;
2971
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972 case HCI_EV_DISCONN_COMPLETE:
2973 hci_disconn_complete_evt(hdev, skb);
2974 break;
2975
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976 case HCI_EV_AUTH_COMPLETE:
2977 hci_auth_complete_evt(hdev, skb);
2978 break;
2979
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002980 case HCI_EV_REMOTE_NAME:
2981 hci_remote_name_evt(hdev, skb);
2982 break;
2983
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984 case HCI_EV_ENCRYPT_CHANGE:
2985 hci_encrypt_change_evt(hdev, skb);
2986 break;
2987
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002988 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
2989 hci_change_link_key_complete_evt(hdev, skb);
2990 break;
2991
2992 case HCI_EV_REMOTE_FEATURES:
2993 hci_remote_features_evt(hdev, skb);
2994 break;
2995
2996 case HCI_EV_REMOTE_VERSION:
2997 hci_remote_version_evt(hdev, skb);
2998 break;
2999
3000 case HCI_EV_QOS_SETUP_COMPLETE:
3001 hci_qos_setup_complete_evt(hdev, skb);
3002 break;
3003
3004 case HCI_EV_CMD_COMPLETE:
3005 hci_cmd_complete_evt(hdev, skb);
3006 break;
3007
3008 case HCI_EV_CMD_STATUS:
3009 hci_cmd_status_evt(hdev, skb);
3010 break;
3011
3012 case HCI_EV_ROLE_CHANGE:
3013 hci_role_change_evt(hdev, skb);
3014 break;
3015
3016 case HCI_EV_NUM_COMP_PKTS:
3017 hci_num_comp_pkts_evt(hdev, skb);
3018 break;
3019
3020 case HCI_EV_MODE_CHANGE:
3021 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003022 break;
3023
3024 case HCI_EV_PIN_CODE_REQ:
3025 hci_pin_code_request_evt(hdev, skb);
3026 break;
3027
3028 case HCI_EV_LINK_KEY_REQ:
3029 hci_link_key_request_evt(hdev, skb);
3030 break;
3031
3032 case HCI_EV_LINK_KEY_NOTIFY:
3033 hci_link_key_notify_evt(hdev, skb);
3034 break;
3035
3036 case HCI_EV_CLOCK_OFFSET:
3037 hci_clock_offset_evt(hdev, skb);
3038 break;
3039
Marcel Holtmanna8746412008-07-14 20:13:46 +02003040 case HCI_EV_PKT_TYPE_CHANGE:
3041 hci_pkt_type_change_evt(hdev, skb);
3042 break;
3043
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003044 case HCI_EV_PSCAN_REP_MODE:
3045 hci_pscan_rep_mode_evt(hdev, skb);
3046 break;
3047
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003048 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3049 hci_inquiry_result_with_rssi_evt(hdev, skb);
3050 break;
3051
3052 case HCI_EV_REMOTE_EXT_FEATURES:
3053 hci_remote_ext_features_evt(hdev, skb);
3054 break;
3055
3056 case HCI_EV_SYNC_CONN_COMPLETE:
3057 hci_sync_conn_complete_evt(hdev, skb);
3058 break;
3059
3060 case HCI_EV_SYNC_CONN_CHANGED:
3061 hci_sync_conn_changed_evt(hdev, skb);
3062 break;
3063
Marcel Holtmann04837f62006-07-03 10:02:33 +02003064 case HCI_EV_SNIFF_SUBRATE:
3065 hci_sniff_subrate_evt(hdev, skb);
3066 break;
3067
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003068 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3069 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003070 break;
3071
Marcel Holtmann04936842008-07-14 20:13:48 +02003072 case HCI_EV_IO_CAPA_REQUEST:
3073 hci_io_capa_request_evt(hdev, skb);
3074 break;
3075
Johan Hedberg03b555e2011-01-04 15:40:05 +02003076 case HCI_EV_IO_CAPA_REPLY:
3077 hci_io_capa_reply_evt(hdev, skb);
3078 break;
3079
Johan Hedberga5c29682011-02-19 12:05:57 -03003080 case HCI_EV_USER_CONFIRM_REQUEST:
3081 hci_user_confirm_request_evt(hdev, skb);
3082 break;
3083
Marcel Holtmann04936842008-07-14 20:13:48 +02003084 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3085 hci_simple_pair_complete_evt(hdev, skb);
3086 break;
3087
Marcel Holtmann41a96212008-07-14 20:13:48 +02003088 case HCI_EV_REMOTE_HOST_FEATURES:
3089 hci_remote_host_features_evt(hdev, skb);
3090 break;
3091
Ville Tervofcd89c02011-02-10 22:38:47 -03003092 case HCI_EV_LE_META:
3093 hci_le_meta_evt(hdev, skb);
3094 break;
3095
Szymon Janc2763eda2011-03-22 13:12:22 +01003096 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3097 hci_remote_oob_data_request_evt(hdev, skb);
3098 break;
3099
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003100 default:
3101 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003102 break;
3103 }
3104
3105 kfree_skb(skb);
3106 hdev->stat.evt_rx++;
3107}
3108
3109/* Generate internal stack event */
3110void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3111{
3112 struct hci_event_hdr *hdr;
3113 struct hci_ev_stack_internal *ev;
3114 struct sk_buff *skb;
3115
3116 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3117 if (!skb)
3118 return;
3119
3120 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3121 hdr->evt = HCI_EV_STACK_INTERNAL;
3122 hdr->plen = sizeof(*ev) + dlen;
3123
3124 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3125 ev->type = type;
3126 memcpy(ev->data, data, dlen);
3127
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003128 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003129 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003130
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003131 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003132 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003133 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134 kfree_skb(skb);
3135}
Andre Guedese6100a22011-06-30 19:20:54 -03003136
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003137module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003138MODULE_PARM_DESC(enable_le, "Enable LE support");