blob: dfe6fbc8fc9a76832721eaba707d3380e1d2fbc6 [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
Andre Guedese6d465c2011-11-09 17:14:26 -030058 if (status) {
59 hci_dev_lock(hdev);
60 mgmt_stop_discovery_failed(hdev, status);
61 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020062 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030063 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Andre Guedes89352e72011-11-04 14:16:53 -030065 clear_bit(HCI_INQUIRY, &hdev->flags);
66
Johan Hedberg56e5cb82011-11-08 20:40:16 +020067 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +020068 mgmt_discovering(hdev, 0);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020069 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010070
Johan Hedberg23bb5762010-12-21 23:01:27 +020071 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010072
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070074}
75
Marcel Holtmanna9de9242007-10-20 13:33:56 +020076static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070077{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020078 __u8 status = *((__u8 *) skb->data);
79
80 BT_DBG("%s status 0x%x", hdev->name, status);
81
82 if (status)
83 return;
84
Marcel Holtmanna9de9242007-10-20 13:33:56 +020085 hci_conn_check_pending(hdev);
86}
87
88static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
89{
90 BT_DBG("%s", hdev->name);
91}
92
93static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
94{
95 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Marcel Holtmanna9de9242007-10-20 13:33:56 +020098 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 if (rp->status)
101 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200103 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
106 if (conn) {
107 if (rp->role)
108 conn->link_mode &= ~HCI_LM_MASTER;
109 else
110 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200112
113 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114}
115
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200116static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
117{
118 struct hci_rp_read_link_policy *rp = (void *) skb->data;
119 struct hci_conn *conn;
120
121 BT_DBG("%s status 0x%x", hdev->name, rp->status);
122
123 if (rp->status)
124 return;
125
126 hci_dev_lock(hdev);
127
128 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
129 if (conn)
130 conn->link_policy = __le16_to_cpu(rp->policy);
131
132 hci_dev_unlock(hdev);
133}
134
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200137 struct hci_rp_write_link_policy *rp = (void *) skb->data;
138 struct hci_conn *conn;
139 void *sent;
140
141 BT_DBG("%s status 0x%x", hdev->name, rp->status);
142
143 if (rp->status)
144 return;
145
146 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
147 if (!sent)
148 return;
149
150 hci_dev_lock(hdev);
151
152 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200153 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700154 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200155
156 hci_dev_unlock(hdev);
157}
158
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200159static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
160{
161 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
162
163 BT_DBG("%s status 0x%x", hdev->name, rp->status);
164
165 if (rp->status)
166 return;
167
168 hdev->link_policy = __le16_to_cpu(rp->policy);
169}
170
171static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
172{
173 __u8 status = *((__u8 *) skb->data);
174 void *sent;
175
176 BT_DBG("%s status 0x%x", hdev->name, status);
177
178 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
179 if (!sent)
180 return;
181
182 if (!status)
183 hdev->link_policy = get_unaligned_le16(sent);
184
Johan Hedberg23bb5762010-12-21 23:01:27 +0200185 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200186}
187
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200188static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
189{
190 __u8 status = *((__u8 *) skb->data);
191
192 BT_DBG("%s status 0x%x", hdev->name, status);
193
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300194 clear_bit(HCI_RESET, &hdev->flags);
195
Johan Hedberg23bb5762010-12-21 23:01:27 +0200196 hci_req_complete(hdev, HCI_OP_RESET, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200197}
198
199static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
200{
201 __u8 status = *((__u8 *) skb->data);
202 void *sent;
203
204 BT_DBG("%s status 0x%x", hdev->name, status);
205
206 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
207 if (!sent)
208 return;
209
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200210 hci_dev_lock(hdev);
211
Johan Hedbergb312b1612011-03-16 14:29:37 +0200212 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200213 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200214
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200215 if (status == 0)
216 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200219}
220
221static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
222{
223 struct hci_rp_read_local_name *rp = (void *) skb->data;
224
225 BT_DBG("%s status 0x%x", hdev->name, rp->status);
226
227 if (rp->status)
228 return;
229
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200230 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200231}
232
233static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
234{
235 __u8 status = *((__u8 *) skb->data);
236 void *sent;
237
238 BT_DBG("%s status 0x%x", hdev->name, status);
239
240 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
241 if (!sent)
242 return;
243
244 if (!status) {
245 __u8 param = *((__u8 *) sent);
246
247 if (param == AUTH_ENABLED)
248 set_bit(HCI_AUTH, &hdev->flags);
249 else
250 clear_bit(HCI_AUTH, &hdev->flags);
251 }
252
Johan Hedberg23bb5762010-12-21 23:01:27 +0200253 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200254}
255
256static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
257{
258 __u8 status = *((__u8 *) skb->data);
259 void *sent;
260
261 BT_DBG("%s status 0x%x", hdev->name, status);
262
263 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
264 if (!sent)
265 return;
266
267 if (!status) {
268 __u8 param = *((__u8 *) sent);
269
270 if (param)
271 set_bit(HCI_ENCRYPT, &hdev->flags);
272 else
273 clear_bit(HCI_ENCRYPT, &hdev->flags);
274 }
275
Johan Hedberg23bb5762010-12-21 23:01:27 +0200276 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200277}
278
279static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
280{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200281 __u8 param, status = *((__u8 *) skb->data);
282 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200283 void *sent;
284
285 BT_DBG("%s status 0x%x", hdev->name, status);
286
287 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
288 if (!sent)
289 return;
290
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200291 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200292
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200293 hci_dev_lock(hdev);
294
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200295 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200296 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200297 hdev->discov_timeout = 0;
298 goto done;
299 }
300
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200301 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
302 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200303
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200304 if (param & SCAN_INQUIRY) {
305 set_bit(HCI_ISCAN, &hdev->flags);
306 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200307 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200308 if (hdev->discov_timeout > 0) {
309 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
310 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
311 to);
312 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200313 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200314 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200315
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200316 if (param & SCAN_PAGE) {
317 set_bit(HCI_PSCAN, &hdev->flags);
318 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200319 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200320 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200321 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200322
323done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200324 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200325 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200326}
327
328static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
329{
330 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
331
332 BT_DBG("%s status 0x%x", hdev->name, rp->status);
333
334 if (rp->status)
335 return;
336
337 memcpy(hdev->dev_class, rp->dev_class, 3);
338
339 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
340 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
341}
342
343static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
344{
345 __u8 status = *((__u8 *) skb->data);
346 void *sent;
347
348 BT_DBG("%s status 0x%x", hdev->name, status);
349
Marcel Holtmannf383f272008-07-14 20:13:47 +0200350 if (status)
351 return;
352
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200353 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
354 if (!sent)
355 return;
356
Marcel Holtmannf383f272008-07-14 20:13:47 +0200357 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200358}
359
360static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
361{
362 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200364
365 BT_DBG("%s status 0x%x", hdev->name, rp->status);
366
367 if (rp->status)
368 return;
369
370 setting = __le16_to_cpu(rp->voice_setting);
371
Marcel Holtmannf383f272008-07-14 20:13:47 +0200372 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200373 return;
374
375 hdev->voice_setting = setting;
376
377 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
378
379 if (hdev->notify) {
380 tasklet_disable(&hdev->tx_task);
381 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
382 tasklet_enable(&hdev->tx_task);
383 }
384}
385
386static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
387{
388 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200389 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 void *sent;
391
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393
Marcel Holtmannf383f272008-07-14 20:13:47 +0200394 if (status)
395 return;
396
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200397 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
398 if (!sent)
399 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
Marcel Holtmannf383f272008-07-14 20:13:47 +0200401 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Marcel Holtmannf383f272008-07-14 20:13:47 +0200403 if (hdev->voice_setting == setting)
404 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405
Marcel Holtmannf383f272008-07-14 20:13:47 +0200406 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
409
410 if (hdev->notify) {
411 tasklet_disable(&hdev->tx_task);
412 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
413 tasklet_enable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 }
415}
416
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200417static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200419 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200421 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422
Johan Hedberg23bb5762010-12-21 23:01:27 +0200423 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424}
425
Marcel Holtmann333140b2008-07-14 20:13:48 +0200426static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
427{
428 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
429
430 BT_DBG("%s status 0x%x", hdev->name, rp->status);
431
432 if (rp->status)
433 return;
434
435 hdev->ssp_mode = rp->mode;
436}
437
438static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
439{
440 __u8 status = *((__u8 *) skb->data);
441 void *sent;
442
443 BT_DBG("%s status 0x%x", hdev->name, status);
444
445 if (status)
446 return;
447
448 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
449 if (!sent)
450 return;
451
452 hdev->ssp_mode = *((__u8 *) sent);
453}
454
Johan Hedbergd5859e22011-01-25 01:19:58 +0200455static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
456{
457 if (hdev->features[6] & LMP_EXT_INQ)
458 return 2;
459
460 if (hdev->features[3] & LMP_RSSI_INQ)
461 return 1;
462
463 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
464 hdev->lmp_subver == 0x0757)
465 return 1;
466
467 if (hdev->manufacturer == 15) {
468 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
469 return 1;
470 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
471 return 1;
472 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
473 return 1;
474 }
475
476 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
477 hdev->lmp_subver == 0x1805)
478 return 1;
479
480 return 0;
481}
482
483static void hci_setup_inquiry_mode(struct hci_dev *hdev)
484{
485 u8 mode;
486
487 mode = hci_get_inquiry_mode(hdev);
488
489 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
490}
491
492static void hci_setup_event_mask(struct hci_dev *hdev)
493{
494 /* The second byte is 0xff instead of 0x9f (two reserved bits
495 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
496 * command otherwise */
497 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
498
Ville Tervo6de6c182011-05-27 11:16:21 +0300499 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
500 * any event mask for pre 1.2 devices */
501 if (hdev->lmp_ver <= 1)
502 return;
503
504 events[4] |= 0x01; /* Flow Specification Complete */
505 events[4] |= 0x02; /* Inquiry Result with RSSI */
506 events[4] |= 0x04; /* Read Remote Extended Features Complete */
507 events[5] |= 0x08; /* Synchronous Connection Complete */
508 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200509
510 if (hdev->features[3] & LMP_RSSI_INQ)
511 events[4] |= 0x04; /* Inquiry Result with RSSI */
512
513 if (hdev->features[5] & LMP_SNIFF_SUBR)
514 events[5] |= 0x20; /* Sniff Subrating */
515
516 if (hdev->features[5] & LMP_PAUSE_ENC)
517 events[5] |= 0x80; /* Encryption Key Refresh Complete */
518
519 if (hdev->features[6] & LMP_EXT_INQ)
520 events[5] |= 0x40; /* Extended Inquiry Result */
521
522 if (hdev->features[6] & LMP_NO_FLUSH)
523 events[7] |= 0x01; /* Enhanced Flush Complete */
524
525 if (hdev->features[7] & LMP_LSTO)
526 events[6] |= 0x80; /* Link Supervision Timeout Changed */
527
528 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
529 events[6] |= 0x01; /* IO Capability Request */
530 events[6] |= 0x02; /* IO Capability Response */
531 events[6] |= 0x04; /* User Confirmation Request */
532 events[6] |= 0x08; /* User Passkey Request */
533 events[6] |= 0x10; /* Remote OOB Data Request */
534 events[6] |= 0x20; /* Simple Pairing Complete */
535 events[7] |= 0x04; /* User Passkey Notification */
536 events[7] |= 0x08; /* Keypress Notification */
537 events[7] |= 0x10; /* Remote Host Supported
538 * Features Notification */
539 }
540
541 if (hdev->features[4] & LMP_LE)
542 events[7] |= 0x20; /* LE Meta-Event */
543
544 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
545}
546
Andre Guedese6100a22011-06-30 19:20:54 -0300547static void hci_set_le_support(struct hci_dev *hdev)
548{
549 struct hci_cp_write_le_host_supported cp;
550
551 memset(&cp, 0, sizeof(cp));
552
553 if (enable_le) {
554 cp.le = 1;
555 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
556 }
557
558 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
559}
560
Johan Hedbergd5859e22011-01-25 01:19:58 +0200561static void hci_setup(struct hci_dev *hdev)
562{
563 hci_setup_event_mask(hdev);
564
565 if (hdev->lmp_ver > 1)
566 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
567
568 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
569 u8 mode = 0x01;
570 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
571 }
572
573 if (hdev->features[3] & LMP_RSSI_INQ)
574 hci_setup_inquiry_mode(hdev);
575
576 if (hdev->features[7] & LMP_INQ_TX_PWR)
577 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300578
579 if (hdev->features[7] & LMP_EXTFEATURES) {
580 struct hci_cp_read_local_ext_features cp;
581
582 cp.page = 0x01;
583 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
584 sizeof(cp), &cp);
585 }
Andre Guedese6100a22011-06-30 19:20:54 -0300586
587 if (hdev->features[4] & LMP_LE)
588 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200589}
590
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200591static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
592{
593 struct hci_rp_read_local_version *rp = (void *) skb->data;
594
595 BT_DBG("%s status 0x%x", hdev->name, rp->status);
596
597 if (rp->status)
598 return;
599
600 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200601 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200602 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200603 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200604 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200605
606 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
607 hdev->manufacturer,
608 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200609
610 if (test_bit(HCI_INIT, &hdev->flags))
611 hci_setup(hdev);
612}
613
614static void hci_setup_link_policy(struct hci_dev *hdev)
615{
616 u16 link_policy = 0;
617
618 if (hdev->features[0] & LMP_RSWITCH)
619 link_policy |= HCI_LP_RSWITCH;
620 if (hdev->features[0] & LMP_HOLD)
621 link_policy |= HCI_LP_HOLD;
622 if (hdev->features[0] & LMP_SNIFF)
623 link_policy |= HCI_LP_SNIFF;
624 if (hdev->features[1] & LMP_PARK)
625 link_policy |= HCI_LP_PARK;
626
627 link_policy = cpu_to_le16(link_policy);
628 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
629 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200630}
631
632static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
633{
634 struct hci_rp_read_local_commands *rp = (void *) skb->data;
635
636 BT_DBG("%s status 0x%x", hdev->name, rp->status);
637
638 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200639 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200640
641 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200642
643 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
644 hci_setup_link_policy(hdev);
645
646done:
647 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200648}
649
650static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
651{
652 struct hci_rp_read_local_features *rp = (void *) skb->data;
653
654 BT_DBG("%s status 0x%x", hdev->name, rp->status);
655
656 if (rp->status)
657 return;
658
659 memcpy(hdev->features, rp->features, 8);
660
661 /* Adjust default settings according to features
662 * supported by device. */
663
664 if (hdev->features[0] & LMP_3SLOT)
665 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
666
667 if (hdev->features[0] & LMP_5SLOT)
668 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
669
670 if (hdev->features[1] & LMP_HV2) {
671 hdev->pkt_type |= (HCI_HV2);
672 hdev->esco_type |= (ESCO_HV2);
673 }
674
675 if (hdev->features[1] & LMP_HV3) {
676 hdev->pkt_type |= (HCI_HV3);
677 hdev->esco_type |= (ESCO_HV3);
678 }
679
680 if (hdev->features[3] & LMP_ESCO)
681 hdev->esco_type |= (ESCO_EV3);
682
683 if (hdev->features[4] & LMP_EV4)
684 hdev->esco_type |= (ESCO_EV4);
685
686 if (hdev->features[4] & LMP_EV5)
687 hdev->esco_type |= (ESCO_EV5);
688
Marcel Holtmannefc76882009-02-06 09:13:37 +0100689 if (hdev->features[5] & LMP_EDR_ESCO_2M)
690 hdev->esco_type |= (ESCO_2EV3);
691
692 if (hdev->features[5] & LMP_EDR_ESCO_3M)
693 hdev->esco_type |= (ESCO_3EV3);
694
695 if (hdev->features[5] & LMP_EDR_3S_ESCO)
696 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
697
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200698 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
699 hdev->features[0], hdev->features[1],
700 hdev->features[2], hdev->features[3],
701 hdev->features[4], hdev->features[5],
702 hdev->features[6], hdev->features[7]);
703}
704
Andre Guedes971e3a42011-06-30 19:20:52 -0300705static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
706 struct sk_buff *skb)
707{
708 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
709
710 BT_DBG("%s status 0x%x", hdev->name, rp->status);
711
712 if (rp->status)
713 return;
714
715 memcpy(hdev->extfeatures, rp->features, 8);
716
717 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
718}
719
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200720static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
721{
722 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
723
724 BT_DBG("%s status 0x%x", hdev->name, rp->status);
725
726 if (rp->status)
727 return;
728
729 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
730 hdev->sco_mtu = rp->sco_mtu;
731 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
732 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
733
734 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
735 hdev->sco_mtu = 64;
736 hdev->sco_pkts = 8;
737 }
738
739 hdev->acl_cnt = hdev->acl_pkts;
740 hdev->sco_cnt = hdev->sco_pkts;
741
742 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
743 hdev->acl_mtu, hdev->acl_pkts,
744 hdev->sco_mtu, hdev->sco_pkts);
745}
746
747static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
748{
749 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
750
751 BT_DBG("%s status 0x%x", hdev->name, rp->status);
752
753 if (!rp->status)
754 bacpy(&hdev->bdaddr, &rp->bdaddr);
755
Johan Hedberg23bb5762010-12-21 23:01:27 +0200756 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
757}
758
759static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
760{
761 __u8 status = *((__u8 *) skb->data);
762
763 BT_DBG("%s status 0x%x", hdev->name, status);
764
765 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200766}
767
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300768static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
769 struct sk_buff *skb)
770{
771 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
772
773 BT_DBG("%s status 0x%x", hdev->name, rp->status);
774
775 if (rp->status)
776 return;
777
778 hdev->amp_status = rp->amp_status;
779 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
780 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
781 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
782 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
783 hdev->amp_type = rp->amp_type;
784 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
785 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
786 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
787 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
788
789 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
790}
791
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200792static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
793 struct sk_buff *skb)
794{
795 __u8 status = *((__u8 *) skb->data);
796
797 BT_DBG("%s status 0x%x", hdev->name, status);
798
799 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
800}
801
Johan Hedbergd5859e22011-01-25 01:19:58 +0200802static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
803{
804 __u8 status = *((__u8 *) skb->data);
805
806 BT_DBG("%s status 0x%x", hdev->name, status);
807
808 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
809}
810
811static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
812 struct sk_buff *skb)
813{
814 __u8 status = *((__u8 *) skb->data);
815
816 BT_DBG("%s status 0x%x", hdev->name, status);
817
818 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
819}
820
821static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
822 struct sk_buff *skb)
823{
824 __u8 status = *((__u8 *) skb->data);
825
826 BT_DBG("%s status 0x%x", hdev->name, status);
827
828 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
829}
830
831static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
832{
833 __u8 status = *((__u8 *) skb->data);
834
835 BT_DBG("%s status 0x%x", hdev->name, status);
836
837 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
838}
839
Johan Hedberg980e1a52011-01-22 06:10:07 +0200840static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
841{
842 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
843 struct hci_cp_pin_code_reply *cp;
844 struct hci_conn *conn;
845
846 BT_DBG("%s status 0x%x", hdev->name, rp->status);
847
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200848 hci_dev_lock(hdev);
849
Johan Hedberg980e1a52011-01-22 06:10:07 +0200850 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200851 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200852
853 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200854 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200855
856 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
857 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200858 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200859
860 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
861 if (conn)
862 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200863
864unlock:
865 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200866}
867
868static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
869{
870 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
871
872 BT_DBG("%s status 0x%x", hdev->name, rp->status);
873
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200874 hci_dev_lock(hdev);
875
Johan Hedberg980e1a52011-01-22 06:10:07 +0200876 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200877 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200878 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200879
880 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200881}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200882
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300883static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
884 struct sk_buff *skb)
885{
886 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
887
888 BT_DBG("%s status 0x%x", hdev->name, rp->status);
889
890 if (rp->status)
891 return;
892
893 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
894 hdev->le_pkts = rp->le_max_pkt;
895
896 hdev->le_cnt = hdev->le_pkts;
897
898 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
899
900 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
901}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200902
Johan Hedberga5c29682011-02-19 12:05:57 -0300903static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
904{
905 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
906
907 BT_DBG("%s status 0x%x", hdev->name, rp->status);
908
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200909 hci_dev_lock(hdev);
910
Johan Hedberga5c29682011-02-19 12:05:57 -0300911 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200912 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300913 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200914
915 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300916}
917
918static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
919 struct sk_buff *skb)
920{
921 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
922
923 BT_DBG("%s status 0x%x", hdev->name, rp->status);
924
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200925 hci_dev_lock(hdev);
926
Johan Hedberga5c29682011-02-19 12:05:57 -0300927 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200928 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300929 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200930
931 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300932}
933
Szymon Jancc35938b2011-03-22 13:12:21 +0100934static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
935 struct sk_buff *skb)
936{
937 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
938
939 BT_DBG("%s status 0x%x", hdev->name, rp->status);
940
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200941 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200942 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100943 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200944 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100945}
946
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300947static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
948 struct sk_buff *skb)
949{
950 struct hci_cp_le_set_scan_enable *cp;
951 __u8 status = *((__u8 *) skb->data);
952
953 BT_DBG("%s status 0x%x", hdev->name, status);
954
955 if (status)
956 return;
957
958 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
959 if (!cp)
960 return;
961
Andre Guedes35815082011-05-26 16:23:53 -0300962 if (cp->enable == 0x01) {
963 del_timer(&hdev->adv_timer);
Andre Guedesa8f13c82011-09-09 18:56:24 -0300964
965 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300966 hci_adv_entries_clear(hdev);
Andre Guedesa8f13c82011-09-09 18:56:24 -0300967 hci_dev_unlock(hdev);
Andre Guedes35815082011-05-26 16:23:53 -0300968 } else if (cp->enable == 0x00) {
969 mod_timer(&hdev->adv_timer, jiffies + ADV_CLEAR_TIMEOUT);
970 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300971}
972
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -0300973static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
974{
975 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
976
977 BT_DBG("%s status 0x%x", hdev->name, rp->status);
978
979 if (rp->status)
980 return;
981
982 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
983}
984
985static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
986{
987 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
988
989 BT_DBG("%s status 0x%x", hdev->name, rp->status);
990
991 if (rp->status)
992 return;
993
994 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
995}
996
Andre Guedesf9b49302011-06-30 19:20:53 -0300997static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
998 struct sk_buff *skb)
999{
1000 struct hci_cp_read_local_ext_features cp;
1001 __u8 status = *((__u8 *) skb->data);
1002
1003 BT_DBG("%s status 0x%x", hdev->name, status);
1004
1005 if (status)
1006 return;
1007
1008 cp.page = 0x01;
1009 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1010}
1011
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001012static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1013{
1014 BT_DBG("%s status 0x%x", hdev->name, status);
1015
1016 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001017 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001018 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001019 hci_dev_lock(hdev);
Johan Hedberg164a6e72011-11-01 17:06:44 +02001020 if (test_bit(HCI_MGMT, &hdev->flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001021 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001022 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001023 return;
1024 }
1025
Andre Guedes89352e72011-11-04 14:16:53 -03001026 set_bit(HCI_INQUIRY, &hdev->flags);
1027
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001028 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001029 mgmt_discovering(hdev, 1);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001030 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001031}
1032
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1034{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001035 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001038 BT_DBG("%s status 0x%x", hdev->name, status);
1039
1040 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 if (!cp)
1042 return;
1043
1044 hci_dev_lock(hdev);
1045
1046 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1047
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001048 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049
1050 if (status) {
1051 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001052 if (status != 0x0c || conn->attempt > 2) {
1053 conn->state = BT_CLOSED;
1054 hci_proto_connect_cfm(conn, status);
1055 hci_conn_del(conn);
1056 } else
1057 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 }
1059 } else {
1060 if (!conn) {
1061 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1062 if (conn) {
1063 conn->out = 1;
1064 conn->link_mode |= HCI_LM_MASTER;
1065 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001066 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067 }
1068 }
1069
1070 hci_dev_unlock(hdev);
1071}
1072
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001073static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001075 struct hci_cp_add_sco *cp;
1076 struct hci_conn *acl, *sco;
1077 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001079 BT_DBG("%s status 0x%x", hdev->name, status);
1080
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001081 if (!status)
1082 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001084 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1085 if (!cp)
1086 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001088 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001090 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001091
1092 hci_dev_lock(hdev);
1093
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001094 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001095 if (acl) {
1096 sco = acl->link;
1097 if (sco) {
1098 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001099
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001100 hci_proto_connect_cfm(sco, status);
1101 hci_conn_del(sco);
1102 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001103 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001104
1105 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106}
1107
Marcel Holtmannf8558552008-07-14 20:13:49 +02001108static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1109{
1110 struct hci_cp_auth_requested *cp;
1111 struct hci_conn *conn;
1112
1113 BT_DBG("%s status 0x%x", hdev->name, status);
1114
1115 if (!status)
1116 return;
1117
1118 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1119 if (!cp)
1120 return;
1121
1122 hci_dev_lock(hdev);
1123
1124 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1125 if (conn) {
1126 if (conn->state == BT_CONFIG) {
1127 hci_proto_connect_cfm(conn, status);
1128 hci_conn_put(conn);
1129 }
1130 }
1131
1132 hci_dev_unlock(hdev);
1133}
1134
1135static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1136{
1137 struct hci_cp_set_conn_encrypt *cp;
1138 struct hci_conn *conn;
1139
1140 BT_DBG("%s status 0x%x", hdev->name, status);
1141
1142 if (!status)
1143 return;
1144
1145 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1146 if (!cp)
1147 return;
1148
1149 hci_dev_lock(hdev);
1150
1151 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1152 if (conn) {
1153 if (conn->state == BT_CONFIG) {
1154 hci_proto_connect_cfm(conn, status);
1155 hci_conn_put(conn);
1156 }
1157 }
1158
1159 hci_dev_unlock(hdev);
1160}
1161
Johan Hedberg127178d2010-11-18 22:22:29 +02001162static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001163 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001164{
Johan Hedberg392599b2010-11-18 22:22:28 +02001165 if (conn->state != BT_CONFIG || !conn->out)
1166 return 0;
1167
Johan Hedberg765c2a92011-01-19 12:06:52 +05301168 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001169 return 0;
1170
1171 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001172 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedberg392599b2010-11-18 22:22:28 +02001173 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001174 conn->pending_sec_level != BT_SECURITY_HIGH &&
1175 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001176 return 0;
1177
Johan Hedberg392599b2010-11-18 22:22:28 +02001178 return 1;
1179}
1180
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001181static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1182{
Johan Hedberg127178d2010-11-18 22:22:29 +02001183 struct hci_cp_remote_name_req *cp;
1184 struct hci_conn *conn;
1185
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001186 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001187
1188 /* If successful wait for the name req complete event before
1189 * checking for the need to do authentication */
1190 if (!status)
1191 return;
1192
1193 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1194 if (!cp)
1195 return;
1196
1197 hci_dev_lock(hdev);
1198
1199 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001200 if (!conn)
1201 goto unlock;
1202
1203 if (!hci_outgoing_auth_needed(hdev, conn))
1204 goto unlock;
1205
1206 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001207 struct hci_cp_auth_requested cp;
1208 cp.handle = __cpu_to_le16(conn->handle);
1209 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1210 }
1211
Johan Hedberg79c6c702011-04-28 11:28:55 -07001212unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001213 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001214}
1215
Marcel Holtmann769be972008-07-14 20:13:49 +02001216static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1217{
1218 struct hci_cp_read_remote_features *cp;
1219 struct hci_conn *conn;
1220
1221 BT_DBG("%s status 0x%x", hdev->name, status);
1222
1223 if (!status)
1224 return;
1225
1226 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1227 if (!cp)
1228 return;
1229
1230 hci_dev_lock(hdev);
1231
1232 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1233 if (conn) {
1234 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001235 hci_proto_connect_cfm(conn, status);
1236 hci_conn_put(conn);
1237 }
1238 }
1239
1240 hci_dev_unlock(hdev);
1241}
1242
1243static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1244{
1245 struct hci_cp_read_remote_ext_features *cp;
1246 struct hci_conn *conn;
1247
1248 BT_DBG("%s status 0x%x", hdev->name, status);
1249
1250 if (!status)
1251 return;
1252
1253 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1254 if (!cp)
1255 return;
1256
1257 hci_dev_lock(hdev);
1258
1259 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1260 if (conn) {
1261 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001262 hci_proto_connect_cfm(conn, status);
1263 hci_conn_put(conn);
1264 }
1265 }
1266
1267 hci_dev_unlock(hdev);
1268}
1269
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001270static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1271{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001272 struct hci_cp_setup_sync_conn *cp;
1273 struct hci_conn *acl, *sco;
1274 __u16 handle;
1275
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001276 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001277
1278 if (!status)
1279 return;
1280
1281 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1282 if (!cp)
1283 return;
1284
1285 handle = __le16_to_cpu(cp->handle);
1286
1287 BT_DBG("%s handle %d", hdev->name, handle);
1288
1289 hci_dev_lock(hdev);
1290
1291 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001292 if (acl) {
1293 sco = acl->link;
1294 if (sco) {
1295 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001296
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001297 hci_proto_connect_cfm(sco, status);
1298 hci_conn_del(sco);
1299 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001300 }
1301
1302 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001303}
1304
1305static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1306{
1307 struct hci_cp_sniff_mode *cp;
1308 struct hci_conn *conn;
1309
1310 BT_DBG("%s status 0x%x", hdev->name, status);
1311
1312 if (!status)
1313 return;
1314
1315 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1316 if (!cp)
1317 return;
1318
1319 hci_dev_lock(hdev);
1320
1321 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001322 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001323 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1324
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001325 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1326 hci_sco_setup(conn, status);
1327 }
1328
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001329 hci_dev_unlock(hdev);
1330}
1331
1332static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1333{
1334 struct hci_cp_exit_sniff_mode *cp;
1335 struct hci_conn *conn;
1336
1337 BT_DBG("%s status 0x%x", hdev->name, status);
1338
1339 if (!status)
1340 return;
1341
1342 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1343 if (!cp)
1344 return;
1345
1346 hci_dev_lock(hdev);
1347
1348 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001349 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001350 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1351
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001352 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1353 hci_sco_setup(conn, status);
1354 }
1355
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001356 hci_dev_unlock(hdev);
1357}
1358
Ville Tervofcd89c02011-02-10 22:38:47 -03001359static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1360{
1361 struct hci_cp_le_create_conn *cp;
1362 struct hci_conn *conn;
1363
1364 BT_DBG("%s status 0x%x", hdev->name, status);
1365
1366 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1367 if (!cp)
1368 return;
1369
1370 hci_dev_lock(hdev);
1371
1372 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1373
1374 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1375 conn);
1376
1377 if (status) {
1378 if (conn && conn->state == BT_CONNECT) {
1379 conn->state = BT_CLOSED;
1380 hci_proto_connect_cfm(conn, status);
1381 hci_conn_del(conn);
1382 }
1383 } else {
1384 if (!conn) {
1385 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001386 if (conn) {
1387 conn->dst_type = cp->peer_addr_type;
Ville Tervofcd89c02011-02-10 22:38:47 -03001388 conn->out = 1;
Andre Guedes29b79882011-05-31 14:20:54 -03001389 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001390 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001391 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001392 }
1393 }
1394
1395 hci_dev_unlock(hdev);
1396}
1397
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001398static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1399{
1400 BT_DBG("%s status 0x%x", hdev->name, status);
1401}
1402
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001403static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1404{
1405 __u8 status = *((__u8 *) skb->data);
1406
1407 BT_DBG("%s status %d", hdev->name, status);
1408
Johan Hedberg23bb5762010-12-21 23:01:27 +02001409 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001410
1411 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001412
1413 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1414 return;
1415
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001416 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001417 mgmt_discovering(hdev, 0);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001418 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001419}
1420
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1422{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001423 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001424 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 int num_rsp = *((__u8 *) skb->data);
1426
1427 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1428
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001429 if (!num_rsp)
1430 return;
1431
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001433
Johan Hedberge17acd42011-03-30 23:57:16 +03001434 for (; num_rsp; num_rsp--, info++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435 bacpy(&data.bdaddr, &info->bdaddr);
1436 data.pscan_rep_mode = info->pscan_rep_mode;
1437 data.pscan_period_mode = info->pscan_period_mode;
1438 data.pscan_mode = info->pscan_mode;
1439 memcpy(data.dev_class, info->dev_class, 3);
1440 data.clock_offset = info->clock_offset;
1441 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001442 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02001444 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg4c659c32011-11-07 23:13:39 +02001445 info->dev_class, 0, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001447
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448 hci_dev_unlock(hdev);
1449}
1450
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001451static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001453 struct hci_ev_conn_complete *ev = (void *) skb->data;
1454 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001456 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001457
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001459
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001460 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001461 if (!conn) {
1462 if (ev->link_type != SCO_LINK)
1463 goto unlock;
1464
1465 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1466 if (!conn)
1467 goto unlock;
1468
1469 conn->type = SCO_LINK;
1470 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001471
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001472 if (!ev->status) {
1473 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001474
1475 if (conn->type == ACL_LINK) {
1476 conn->state = BT_CONFIG;
1477 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001478 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg48264f02011-11-09 13:58:58 +02001479 mgmt_connected(hdev, &ev->bdaddr, conn->type,
1480 conn->dst_type);
Marcel Holtmann769be972008-07-14 20:13:49 +02001481 } else
1482 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001483
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001484 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001485 hci_conn_add_sysfs(conn);
1486
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001487 if (test_bit(HCI_AUTH, &hdev->flags))
1488 conn->link_mode |= HCI_LM_AUTH;
1489
1490 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1491 conn->link_mode |= HCI_LM_ENCRYPT;
1492
1493 /* Get remote features */
1494 if (conn->type == ACL_LINK) {
1495 struct hci_cp_read_remote_features cp;
1496 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001497 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1498 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001499 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001500
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001501 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +02001502 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001503 struct hci_cp_change_conn_ptype cp;
1504 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001505 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1506 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1507 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001508 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001509 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001510 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001511 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001512 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001513 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001514 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001515
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001516 if (conn->type == ACL_LINK)
1517 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001518
Marcel Holtmann769be972008-07-14 20:13:49 +02001519 if (ev->status) {
1520 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001521 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001522 } else if (ev->link_type != ACL_LINK)
1523 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001524
1525unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001527
1528 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529}
1530
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1532{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001533 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 int mask = hdev->link_mode;
1535
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001536 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1537 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538
1539 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1540
Szymon Janc138d22e2011-02-17 16:44:23 +01001541 if ((mask & HCI_LM_ACCEPT) &&
1542 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001544 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546
1547 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001548
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001549 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1550 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001551 memcpy(ie->data.dev_class, ev->dev_class, 3);
1552
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1554 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001555 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1556 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001557 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558 hci_dev_unlock(hdev);
1559 return;
1560 }
1561 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001562
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 memcpy(conn->dev_class, ev->dev_class, 3);
1564 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001565
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566 hci_dev_unlock(hdev);
1567
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001568 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1569 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001571 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001573 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1574 cp.role = 0x00; /* Become master */
1575 else
1576 cp.role = 0x01; /* Remain slave */
1577
1578 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1579 sizeof(cp), &cp);
1580 } else {
1581 struct hci_cp_accept_sync_conn_req cp;
1582
1583 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001584 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001585
1586 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1587 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1588 cp.max_latency = cpu_to_le16(0xffff);
1589 cp.content_format = cpu_to_le16(hdev->voice_setting);
1590 cp.retrans_effort = 0xff;
1591
1592 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1593 sizeof(cp), &cp);
1594 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 } else {
1596 /* Connection rejected */
1597 struct hci_cp_reject_conn_req cp;
1598
1599 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001600 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001601 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 }
1603}
1604
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1606{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001607 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001608 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609
1610 BT_DBG("%s status %d", hdev->name, ev->status);
1611
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 hci_dev_lock(hdev);
1613
Marcel Holtmann04837f62006-07-03 10:02:33 +02001614 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001615 if (!conn)
1616 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001617
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001618 if (ev->status == 0)
1619 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001621 if (conn->type == ACL_LINK || conn->type == LE_LINK) {
1622 if (ev->status != 0)
1623 mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
1624 else
1625 mgmt_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001626 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001627 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001628
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001629 if (ev->status == 0) {
1630 hci_proto_disconn_cfm(conn, ev->reason);
1631 hci_conn_del(conn);
1632 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001633
1634unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635 hci_dev_unlock(hdev);
1636}
1637
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001638static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1639{
1640 struct hci_ev_auth_complete *ev = (void *) skb->data;
1641 struct hci_conn *conn;
1642
1643 BT_DBG("%s status %d", hdev->name, ev->status);
1644
1645 hci_dev_lock(hdev);
1646
1647 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001648 if (!conn)
1649 goto unlock;
1650
1651 if (!ev->status) {
1652 if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) &&
1653 test_bit(HCI_CONN_REAUTH_PEND, &conn->pend)) {
1654 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001655 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001656 conn->link_mode |= HCI_LM_AUTH;
1657 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001658 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001659 } else {
Johan Hedberg744cf192011-11-08 20:40:14 +02001660 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001661 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001662
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001663 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1664 clear_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001665
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001666 if (conn->state == BT_CONFIG) {
1667 if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) {
1668 struct hci_cp_set_conn_encrypt cp;
1669 cp.handle = ev->handle;
1670 cp.encrypt = 0x01;
1671 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1672 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001673 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001674 conn->state = BT_CONNECTED;
1675 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001676 hci_conn_put(conn);
1677 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001678 } else {
1679 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001680
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001681 hci_conn_hold(conn);
1682 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1683 hci_conn_put(conn);
1684 }
1685
1686 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1687 if (!ev->status) {
1688 struct hci_cp_set_conn_encrypt cp;
1689 cp.handle = ev->handle;
1690 cp.encrypt = 0x01;
1691 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1692 &cp);
1693 } else {
1694 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1695 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001696 }
1697 }
1698
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001699unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001700 hci_dev_unlock(hdev);
1701}
1702
1703static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1704{
Johan Hedberg127178d2010-11-18 22:22:29 +02001705 struct hci_ev_remote_name *ev = (void *) skb->data;
1706 struct hci_conn *conn;
1707
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001708 BT_DBG("%s", hdev->name);
1709
1710 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001711
1712 hci_dev_lock(hdev);
1713
Johan Hedberga88a9652011-03-30 13:18:12 +03001714 if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001715 mgmt_remote_name(hdev, &ev->bdaddr, ev->name);
Johan Hedberga88a9652011-03-30 13:18:12 +03001716
Johan Hedberg127178d2010-11-18 22:22:29 +02001717 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001718 if (!conn)
1719 goto unlock;
1720
1721 if (!hci_outgoing_auth_needed(hdev, conn))
1722 goto unlock;
1723
1724 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001725 struct hci_cp_auth_requested cp;
1726 cp.handle = __cpu_to_le16(conn->handle);
1727 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1728 }
1729
Johan Hedberg79c6c702011-04-28 11:28:55 -07001730unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001731 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001732}
1733
1734static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1735{
1736 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1737 struct hci_conn *conn;
1738
1739 BT_DBG("%s status %d", hdev->name, ev->status);
1740
1741 hci_dev_lock(hdev);
1742
1743 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1744 if (conn) {
1745 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001746 if (ev->encrypt) {
1747 /* Encryption implies authentication */
1748 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001749 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001750 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001751 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001752 conn->link_mode &= ~HCI_LM_ENCRYPT;
1753 }
1754
1755 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1756
Marcel Holtmannf8558552008-07-14 20:13:49 +02001757 if (conn->state == BT_CONFIG) {
1758 if (!ev->status)
1759 conn->state = BT_CONNECTED;
1760
1761 hci_proto_connect_cfm(conn, ev->status);
1762 hci_conn_put(conn);
1763 } else
1764 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001765 }
1766
1767 hci_dev_unlock(hdev);
1768}
1769
1770static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1771{
1772 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1773 struct hci_conn *conn;
1774
1775 BT_DBG("%s status %d", hdev->name, ev->status);
1776
1777 hci_dev_lock(hdev);
1778
1779 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1780 if (conn) {
1781 if (!ev->status)
1782 conn->link_mode |= HCI_LM_SECURE;
1783
1784 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1785
1786 hci_key_change_cfm(conn, ev->status);
1787 }
1788
1789 hci_dev_unlock(hdev);
1790}
1791
1792static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1793{
1794 struct hci_ev_remote_features *ev = (void *) skb->data;
1795 struct hci_conn *conn;
1796
1797 BT_DBG("%s status %d", hdev->name, ev->status);
1798
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001799 hci_dev_lock(hdev);
1800
1801 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001802 if (!conn)
1803 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001804
Johan Hedbergccd556f2010-11-10 17:11:51 +02001805 if (!ev->status)
1806 memcpy(conn->features, ev->features, 8);
1807
1808 if (conn->state != BT_CONFIG)
1809 goto unlock;
1810
1811 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1812 struct hci_cp_read_remote_ext_features cp;
1813 cp.handle = ev->handle;
1814 cp.page = 0x01;
1815 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001816 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001817 goto unlock;
1818 }
1819
Johan Hedberg127178d2010-11-18 22:22:29 +02001820 if (!ev->status) {
1821 struct hci_cp_remote_name_req cp;
1822 memset(&cp, 0, sizeof(cp));
1823 bacpy(&cp.bdaddr, &conn->dst);
1824 cp.pscan_rep_mode = 0x02;
1825 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1826 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001827
Johan Hedberg127178d2010-11-18 22:22:29 +02001828 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001829 conn->state = BT_CONNECTED;
1830 hci_proto_connect_cfm(conn, ev->status);
1831 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001832 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001833
Johan Hedbergccd556f2010-11-10 17:11:51 +02001834unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001835 hci_dev_unlock(hdev);
1836}
1837
1838static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1839{
1840 BT_DBG("%s", hdev->name);
1841}
1842
1843static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1844{
1845 BT_DBG("%s", hdev->name);
1846}
1847
1848static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1849{
1850 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1851 __u16 opcode;
1852
1853 skb_pull(skb, sizeof(*ev));
1854
1855 opcode = __le16_to_cpu(ev->opcode);
1856
1857 switch (opcode) {
1858 case HCI_OP_INQUIRY_CANCEL:
1859 hci_cc_inquiry_cancel(hdev, skb);
1860 break;
1861
1862 case HCI_OP_EXIT_PERIODIC_INQ:
1863 hci_cc_exit_periodic_inq(hdev, skb);
1864 break;
1865
1866 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1867 hci_cc_remote_name_req_cancel(hdev, skb);
1868 break;
1869
1870 case HCI_OP_ROLE_DISCOVERY:
1871 hci_cc_role_discovery(hdev, skb);
1872 break;
1873
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001874 case HCI_OP_READ_LINK_POLICY:
1875 hci_cc_read_link_policy(hdev, skb);
1876 break;
1877
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001878 case HCI_OP_WRITE_LINK_POLICY:
1879 hci_cc_write_link_policy(hdev, skb);
1880 break;
1881
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001882 case HCI_OP_READ_DEF_LINK_POLICY:
1883 hci_cc_read_def_link_policy(hdev, skb);
1884 break;
1885
1886 case HCI_OP_WRITE_DEF_LINK_POLICY:
1887 hci_cc_write_def_link_policy(hdev, skb);
1888 break;
1889
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001890 case HCI_OP_RESET:
1891 hci_cc_reset(hdev, skb);
1892 break;
1893
1894 case HCI_OP_WRITE_LOCAL_NAME:
1895 hci_cc_write_local_name(hdev, skb);
1896 break;
1897
1898 case HCI_OP_READ_LOCAL_NAME:
1899 hci_cc_read_local_name(hdev, skb);
1900 break;
1901
1902 case HCI_OP_WRITE_AUTH_ENABLE:
1903 hci_cc_write_auth_enable(hdev, skb);
1904 break;
1905
1906 case HCI_OP_WRITE_ENCRYPT_MODE:
1907 hci_cc_write_encrypt_mode(hdev, skb);
1908 break;
1909
1910 case HCI_OP_WRITE_SCAN_ENABLE:
1911 hci_cc_write_scan_enable(hdev, skb);
1912 break;
1913
1914 case HCI_OP_READ_CLASS_OF_DEV:
1915 hci_cc_read_class_of_dev(hdev, skb);
1916 break;
1917
1918 case HCI_OP_WRITE_CLASS_OF_DEV:
1919 hci_cc_write_class_of_dev(hdev, skb);
1920 break;
1921
1922 case HCI_OP_READ_VOICE_SETTING:
1923 hci_cc_read_voice_setting(hdev, skb);
1924 break;
1925
1926 case HCI_OP_WRITE_VOICE_SETTING:
1927 hci_cc_write_voice_setting(hdev, skb);
1928 break;
1929
1930 case HCI_OP_HOST_BUFFER_SIZE:
1931 hci_cc_host_buffer_size(hdev, skb);
1932 break;
1933
Marcel Holtmann333140b2008-07-14 20:13:48 +02001934 case HCI_OP_READ_SSP_MODE:
1935 hci_cc_read_ssp_mode(hdev, skb);
1936 break;
1937
1938 case HCI_OP_WRITE_SSP_MODE:
1939 hci_cc_write_ssp_mode(hdev, skb);
1940 break;
1941
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001942 case HCI_OP_READ_LOCAL_VERSION:
1943 hci_cc_read_local_version(hdev, skb);
1944 break;
1945
1946 case HCI_OP_READ_LOCAL_COMMANDS:
1947 hci_cc_read_local_commands(hdev, skb);
1948 break;
1949
1950 case HCI_OP_READ_LOCAL_FEATURES:
1951 hci_cc_read_local_features(hdev, skb);
1952 break;
1953
Andre Guedes971e3a42011-06-30 19:20:52 -03001954 case HCI_OP_READ_LOCAL_EXT_FEATURES:
1955 hci_cc_read_local_ext_features(hdev, skb);
1956 break;
1957
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001958 case HCI_OP_READ_BUFFER_SIZE:
1959 hci_cc_read_buffer_size(hdev, skb);
1960 break;
1961
1962 case HCI_OP_READ_BD_ADDR:
1963 hci_cc_read_bd_addr(hdev, skb);
1964 break;
1965
Johan Hedberg23bb5762010-12-21 23:01:27 +02001966 case HCI_OP_WRITE_CA_TIMEOUT:
1967 hci_cc_write_ca_timeout(hdev, skb);
1968 break;
1969
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03001970 case HCI_OP_READ_LOCAL_AMP_INFO:
1971 hci_cc_read_local_amp_info(hdev, skb);
1972 break;
1973
Johan Hedbergb0916ea2011-01-10 13:44:55 +02001974 case HCI_OP_DELETE_STORED_LINK_KEY:
1975 hci_cc_delete_stored_link_key(hdev, skb);
1976 break;
1977
Johan Hedbergd5859e22011-01-25 01:19:58 +02001978 case HCI_OP_SET_EVENT_MASK:
1979 hci_cc_set_event_mask(hdev, skb);
1980 break;
1981
1982 case HCI_OP_WRITE_INQUIRY_MODE:
1983 hci_cc_write_inquiry_mode(hdev, skb);
1984 break;
1985
1986 case HCI_OP_READ_INQ_RSP_TX_POWER:
1987 hci_cc_read_inq_rsp_tx_power(hdev, skb);
1988 break;
1989
1990 case HCI_OP_SET_EVENT_FLT:
1991 hci_cc_set_event_flt(hdev, skb);
1992 break;
1993
Johan Hedberg980e1a52011-01-22 06:10:07 +02001994 case HCI_OP_PIN_CODE_REPLY:
1995 hci_cc_pin_code_reply(hdev, skb);
1996 break;
1997
1998 case HCI_OP_PIN_CODE_NEG_REPLY:
1999 hci_cc_pin_code_neg_reply(hdev, skb);
2000 break;
2001
Szymon Jancc35938b2011-03-22 13:12:21 +01002002 case HCI_OP_READ_LOCAL_OOB_DATA:
2003 hci_cc_read_local_oob_data_reply(hdev, skb);
2004 break;
2005
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002006 case HCI_OP_LE_READ_BUFFER_SIZE:
2007 hci_cc_le_read_buffer_size(hdev, skb);
2008 break;
2009
Johan Hedberga5c29682011-02-19 12:05:57 -03002010 case HCI_OP_USER_CONFIRM_REPLY:
2011 hci_cc_user_confirm_reply(hdev, skb);
2012 break;
2013
2014 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2015 hci_cc_user_confirm_neg_reply(hdev, skb);
2016 break;
2017
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002018 case HCI_OP_LE_SET_SCAN_ENABLE:
2019 hci_cc_le_set_scan_enable(hdev, skb);
2020 break;
2021
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002022 case HCI_OP_LE_LTK_REPLY:
2023 hci_cc_le_ltk_reply(hdev, skb);
2024 break;
2025
2026 case HCI_OP_LE_LTK_NEG_REPLY:
2027 hci_cc_le_ltk_neg_reply(hdev, skb);
2028 break;
2029
Andre Guedesf9b49302011-06-30 19:20:53 -03002030 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2031 hci_cc_write_le_host_supported(hdev, skb);
2032 break;
2033
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002034 default:
2035 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2036 break;
2037 }
2038
Ville Tervo6bd32322011-02-16 16:32:41 +02002039 if (ev->opcode != HCI_OP_NOP)
2040 del_timer(&hdev->cmd_timer);
2041
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002042 if (ev->ncmd) {
2043 atomic_set(&hdev->cmd_cnt, 1);
2044 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002045 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002046 }
2047}
2048
2049static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2050{
2051 struct hci_ev_cmd_status *ev = (void *) skb->data;
2052 __u16 opcode;
2053
2054 skb_pull(skb, sizeof(*ev));
2055
2056 opcode = __le16_to_cpu(ev->opcode);
2057
2058 switch (opcode) {
2059 case HCI_OP_INQUIRY:
2060 hci_cs_inquiry(hdev, ev->status);
2061 break;
2062
2063 case HCI_OP_CREATE_CONN:
2064 hci_cs_create_conn(hdev, ev->status);
2065 break;
2066
2067 case HCI_OP_ADD_SCO:
2068 hci_cs_add_sco(hdev, ev->status);
2069 break;
2070
Marcel Holtmannf8558552008-07-14 20:13:49 +02002071 case HCI_OP_AUTH_REQUESTED:
2072 hci_cs_auth_requested(hdev, ev->status);
2073 break;
2074
2075 case HCI_OP_SET_CONN_ENCRYPT:
2076 hci_cs_set_conn_encrypt(hdev, ev->status);
2077 break;
2078
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002079 case HCI_OP_REMOTE_NAME_REQ:
2080 hci_cs_remote_name_req(hdev, ev->status);
2081 break;
2082
Marcel Holtmann769be972008-07-14 20:13:49 +02002083 case HCI_OP_READ_REMOTE_FEATURES:
2084 hci_cs_read_remote_features(hdev, ev->status);
2085 break;
2086
2087 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2088 hci_cs_read_remote_ext_features(hdev, ev->status);
2089 break;
2090
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002091 case HCI_OP_SETUP_SYNC_CONN:
2092 hci_cs_setup_sync_conn(hdev, ev->status);
2093 break;
2094
2095 case HCI_OP_SNIFF_MODE:
2096 hci_cs_sniff_mode(hdev, ev->status);
2097 break;
2098
2099 case HCI_OP_EXIT_SNIFF_MODE:
2100 hci_cs_exit_sniff_mode(hdev, ev->status);
2101 break;
2102
Johan Hedberg8962ee72011-01-20 12:40:27 +02002103 case HCI_OP_DISCONNECT:
2104 if (ev->status != 0)
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002105 mgmt_disconnect_failed(hdev, NULL, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002106 break;
2107
Ville Tervofcd89c02011-02-10 22:38:47 -03002108 case HCI_OP_LE_CREATE_CONN:
2109 hci_cs_le_create_conn(hdev, ev->status);
2110 break;
2111
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002112 case HCI_OP_LE_START_ENC:
2113 hci_cs_le_start_enc(hdev, ev->status);
2114 break;
2115
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002116 default:
2117 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2118 break;
2119 }
2120
Ville Tervo6bd32322011-02-16 16:32:41 +02002121 if (ev->opcode != HCI_OP_NOP)
2122 del_timer(&hdev->cmd_timer);
2123
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002124 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002125 atomic_set(&hdev->cmd_cnt, 1);
2126 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002127 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002128 }
2129}
2130
2131static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2132{
2133 struct hci_ev_role_change *ev = (void *) skb->data;
2134 struct hci_conn *conn;
2135
2136 BT_DBG("%s status %d", hdev->name, ev->status);
2137
2138 hci_dev_lock(hdev);
2139
2140 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2141 if (conn) {
2142 if (!ev->status) {
2143 if (ev->role)
2144 conn->link_mode &= ~HCI_LM_MASTER;
2145 else
2146 conn->link_mode |= HCI_LM_MASTER;
2147 }
2148
2149 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
2150
2151 hci_role_switch_cfm(conn, ev->status, ev->role);
2152 }
2153
2154 hci_dev_unlock(hdev);
2155}
2156
Linus Torvalds1da177e2005-04-16 15:20:36 -07002157static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2158{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002159 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002160 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161 int i;
2162
2163 skb_pull(skb, sizeof(*ev));
2164
2165 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2166
2167 if (skb->len < ev->num_hndl * 4) {
2168 BT_DBG("%s bad parameters", hdev->name);
2169 return;
2170 }
2171
2172 tasklet_disable(&hdev->tx_task);
2173
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002174 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175 struct hci_conn *conn;
2176 __u16 handle, count;
2177
Harvey Harrison83985312008-05-02 16:25:46 -07002178 handle = get_unaligned_le16(ptr++);
2179 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002180
2181 conn = hci_conn_hash_lookup_handle(hdev, handle);
2182 if (conn) {
2183 conn->sent -= count;
2184
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002185 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002186 hdev->acl_cnt += count;
2187 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002188 hdev->acl_cnt = hdev->acl_pkts;
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002189 } else if (conn->type == LE_LINK) {
2190 if (hdev->le_pkts) {
2191 hdev->le_cnt += count;
2192 if (hdev->le_cnt > hdev->le_pkts)
2193 hdev->le_cnt = hdev->le_pkts;
2194 } else {
2195 hdev->acl_cnt += count;
2196 if (hdev->acl_cnt > hdev->acl_pkts)
2197 hdev->acl_cnt = hdev->acl_pkts;
2198 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002199 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002200 hdev->sco_cnt += count;
2201 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002202 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203 }
2204 }
2205 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002206
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002207 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208
2209 tasklet_enable(&hdev->tx_task);
2210}
2211
Marcel Holtmann04837f62006-07-03 10:02:33 +02002212static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002213{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002214 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002215 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002216
2217 BT_DBG("%s status %d", hdev->name, ev->status);
2218
2219 hci_dev_lock(hdev);
2220
Marcel Holtmann04837f62006-07-03 10:02:33 +02002221 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2222 if (conn) {
2223 conn->mode = ev->mode;
2224 conn->interval = __le16_to_cpu(ev->interval);
2225
2226 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
2227 if (conn->mode == HCI_CM_ACTIVE)
2228 conn->power_save = 1;
2229 else
2230 conn->power_save = 0;
2231 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002232
2233 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
2234 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002235 }
2236
2237 hci_dev_unlock(hdev);
2238}
2239
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2241{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002242 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2243 struct hci_conn *conn;
2244
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002245 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002246
2247 hci_dev_lock(hdev);
2248
2249 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002250 if (!conn)
2251 goto unlock;
2252
2253 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002254 hci_conn_hold(conn);
2255 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2256 hci_conn_put(conn);
2257 }
2258
Johan Hedberg03b555e2011-01-04 15:40:05 +02002259 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
2260 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2261 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg582fbe92011-04-28 11:28:58 -07002262 else if (test_bit(HCI_MGMT, &hdev->flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002263 u8 secure;
2264
2265 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2266 secure = 1;
2267 else
2268 secure = 0;
2269
Johan Hedberg744cf192011-11-08 20:40:14 +02002270 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002271 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002272
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002273unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002274 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002275}
2276
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2278{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002279 struct hci_ev_link_key_req *ev = (void *) skb->data;
2280 struct hci_cp_link_key_reply cp;
2281 struct hci_conn *conn;
2282 struct link_key *key;
2283
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002284 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002285
2286 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
2287 return;
2288
2289 hci_dev_lock(hdev);
2290
2291 key = hci_find_link_key(hdev, &ev->bdaddr);
2292 if (!key) {
2293 BT_DBG("%s link key not found for %s", hdev->name,
2294 batostr(&ev->bdaddr));
2295 goto not_found;
2296 }
2297
2298 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2299 batostr(&ev->bdaddr));
2300
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002301 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) &&
2302 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002303 BT_DBG("%s ignoring debug key", hdev->name);
2304 goto not_found;
2305 }
2306
2307 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002308 if (conn) {
2309 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2310 conn->auth_type != 0xff &&
2311 (conn->auth_type & 0x01)) {
2312 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2313 goto not_found;
2314 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002315
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002316 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2317 conn->pending_sec_level == BT_SECURITY_HIGH) {
2318 BT_DBG("%s ignoring key unauthenticated for high \
2319 security", hdev->name);
2320 goto not_found;
2321 }
2322
2323 conn->key_type = key->type;
2324 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002325 }
2326
2327 bacpy(&cp.bdaddr, &ev->bdaddr);
2328 memcpy(cp.link_key, key->val, 16);
2329
2330 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2331
2332 hci_dev_unlock(hdev);
2333
2334 return;
2335
2336not_found:
2337 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2338 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339}
2340
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2342{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002343 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2344 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002345 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002346
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002347 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002348
2349 hci_dev_lock(hdev);
2350
2351 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2352 if (conn) {
2353 hci_conn_hold(conn);
2354 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002355 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002356
2357 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2358 conn->key_type = ev->key_type;
2359
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002360 hci_conn_put(conn);
2361 }
2362
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002363 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002364 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002365 ev->key_type, pin_len);
2366
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002367 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002368}
2369
Marcel Holtmann04837f62006-07-03 10:02:33 +02002370static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2371{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002372 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002373 struct hci_conn *conn;
2374
2375 BT_DBG("%s status %d", hdev->name, ev->status);
2376
2377 hci_dev_lock(hdev);
2378
2379 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002380 if (conn && !ev->status) {
2381 struct inquiry_entry *ie;
2382
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002383 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2384 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002385 ie->data.clock_offset = ev->clock_offset;
2386 ie->timestamp = jiffies;
2387 }
2388 }
2389
2390 hci_dev_unlock(hdev);
2391}
2392
Marcel Holtmanna8746412008-07-14 20:13:46 +02002393static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2394{
2395 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2396 struct hci_conn *conn;
2397
2398 BT_DBG("%s status %d", hdev->name, ev->status);
2399
2400 hci_dev_lock(hdev);
2401
2402 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2403 if (conn && !ev->status)
2404 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2405
2406 hci_dev_unlock(hdev);
2407}
2408
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002409static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2410{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002411 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002412 struct inquiry_entry *ie;
2413
2414 BT_DBG("%s", hdev->name);
2415
2416 hci_dev_lock(hdev);
2417
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002418 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2419 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002420 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2421 ie->timestamp = jiffies;
2422 }
2423
2424 hci_dev_unlock(hdev);
2425}
2426
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002427static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2428{
2429 struct inquiry_data data;
2430 int num_rsp = *((__u8 *) skb->data);
2431
2432 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2433
2434 if (!num_rsp)
2435 return;
2436
2437 hci_dev_lock(hdev);
2438
2439 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002440 struct inquiry_info_with_rssi_and_pscan_mode *info;
2441 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002442
Johan Hedberge17acd42011-03-30 23:57:16 +03002443 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002444 bacpy(&data.bdaddr, &info->bdaddr);
2445 data.pscan_rep_mode = info->pscan_rep_mode;
2446 data.pscan_period_mode = info->pscan_period_mode;
2447 data.pscan_mode = info->pscan_mode;
2448 memcpy(data.dev_class, info->dev_class, 3);
2449 data.clock_offset = info->clock_offset;
2450 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002451 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002452 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002453 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002454 info->dev_class, info->rssi,
2455 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002456 }
2457 } else {
2458 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2459
Johan Hedberge17acd42011-03-30 23:57:16 +03002460 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002461 bacpy(&data.bdaddr, &info->bdaddr);
2462 data.pscan_rep_mode = info->pscan_rep_mode;
2463 data.pscan_period_mode = info->pscan_period_mode;
2464 data.pscan_mode = 0x00;
2465 memcpy(data.dev_class, info->dev_class, 3);
2466 data.clock_offset = info->clock_offset;
2467 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002468 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002469 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002470 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002471 info->dev_class, info->rssi,
2472 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002473 }
2474 }
2475
2476 hci_dev_unlock(hdev);
2477}
2478
2479static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2480{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002481 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2482 struct hci_conn *conn;
2483
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002484 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002485
Marcel Holtmann41a96212008-07-14 20:13:48 +02002486 hci_dev_lock(hdev);
2487
2488 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002489 if (!conn)
2490 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002491
Johan Hedbergccd556f2010-11-10 17:11:51 +02002492 if (!ev->status && ev->page == 0x01) {
2493 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002494
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002495 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2496 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002497 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002498
Johan Hedbergccd556f2010-11-10 17:11:51 +02002499 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002500 }
2501
Johan Hedbergccd556f2010-11-10 17:11:51 +02002502 if (conn->state != BT_CONFIG)
2503 goto unlock;
2504
Johan Hedberg127178d2010-11-18 22:22:29 +02002505 if (!ev->status) {
2506 struct hci_cp_remote_name_req cp;
2507 memset(&cp, 0, sizeof(cp));
2508 bacpy(&cp.bdaddr, &conn->dst);
2509 cp.pscan_rep_mode = 0x02;
2510 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2511 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002512
Johan Hedberg127178d2010-11-18 22:22:29 +02002513 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002514 conn->state = BT_CONNECTED;
2515 hci_proto_connect_cfm(conn, ev->status);
2516 hci_conn_put(conn);
2517 }
2518
2519unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002520 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002521}
2522
2523static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2524{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002525 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2526 struct hci_conn *conn;
2527
2528 BT_DBG("%s status %d", hdev->name, ev->status);
2529
2530 hci_dev_lock(hdev);
2531
2532 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002533 if (!conn) {
2534 if (ev->link_type == ESCO_LINK)
2535 goto unlock;
2536
2537 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2538 if (!conn)
2539 goto unlock;
2540
2541 conn->type = SCO_LINK;
2542 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002543
Marcel Holtmann732547f2009-04-19 19:14:14 +02002544 switch (ev->status) {
2545 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002546 conn->handle = __le16_to_cpu(ev->handle);
2547 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002548
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002549 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002550 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002551 break;
2552
Stephen Coe705e5712010-02-16 11:29:44 -05002553 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002554 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002555 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002556 case 0x1f: /* Unspecified error */
2557 if (conn->out && conn->attempt < 2) {
2558 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2559 (hdev->esco_type & EDR_ESCO_MASK);
2560 hci_setup_sync(conn, conn->link->handle);
2561 goto unlock;
2562 }
2563 /* fall through */
2564
2565 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002566 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002567 break;
2568 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002569
2570 hci_proto_connect_cfm(conn, ev->status);
2571 if (ev->status)
2572 hci_conn_del(conn);
2573
2574unlock:
2575 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002576}
2577
2578static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2579{
2580 BT_DBG("%s", hdev->name);
2581}
2582
Marcel Holtmann04837f62006-07-03 10:02:33 +02002583static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2584{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002585 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002586
2587 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002588}
2589
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002590static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2591{
2592 struct inquiry_data data;
2593 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2594 int num_rsp = *((__u8 *) skb->data);
2595
2596 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2597
2598 if (!num_rsp)
2599 return;
2600
2601 hci_dev_lock(hdev);
2602
Johan Hedberge17acd42011-03-30 23:57:16 +03002603 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002604 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002605 data.pscan_rep_mode = info->pscan_rep_mode;
2606 data.pscan_period_mode = info->pscan_period_mode;
2607 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002608 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002609 data.clock_offset = info->clock_offset;
2610 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002611 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002612 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002613 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg4c659c32011-11-07 23:13:39 +02002614 info->dev_class, info->rssi, info->data);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002615 }
2616
2617 hci_dev_unlock(hdev);
2618}
2619
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002620static inline u8 hci_get_auth_req(struct hci_conn *conn)
2621{
2622 /* If remote requests dedicated bonding follow that lead */
2623 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2624 /* If both remote and local IO capabilities allow MITM
2625 * protection then require it, otherwise don't */
2626 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2627 return 0x02;
2628 else
2629 return 0x03;
2630 }
2631
2632 /* If remote requests no-bonding follow that lead */
2633 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002634 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002635
2636 return conn->auth_type;
2637}
2638
Marcel Holtmann04936842008-07-14 20:13:48 +02002639static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2640{
2641 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2642 struct hci_conn *conn;
2643
2644 BT_DBG("%s", hdev->name);
2645
2646 hci_dev_lock(hdev);
2647
2648 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002649 if (!conn)
2650 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002651
Johan Hedberg03b555e2011-01-04 15:40:05 +02002652 hci_conn_hold(conn);
2653
2654 if (!test_bit(HCI_MGMT, &hdev->flags))
2655 goto unlock;
2656
2657 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
2658 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002659 struct hci_cp_io_capability_reply cp;
2660
2661 bacpy(&cp.bdaddr, &ev->bdaddr);
2662 cp.capability = conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07002663 conn->auth_type = hci_get_auth_req(conn);
2664 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002665
Szymon Jancce85ee12011-03-22 13:12:23 +01002666 if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
2667 hci_find_remote_oob_data(hdev, &conn->dst))
2668 cp.oob_data = 0x01;
2669 else
2670 cp.oob_data = 0x00;
2671
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002672 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2673 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002674 } else {
2675 struct hci_cp_io_capability_neg_reply cp;
2676
2677 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002678 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02002679
2680 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2681 sizeof(cp), &cp);
2682 }
2683
2684unlock:
2685 hci_dev_unlock(hdev);
2686}
2687
2688static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2689{
2690 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2691 struct hci_conn *conn;
2692
2693 BT_DBG("%s", hdev->name);
2694
2695 hci_dev_lock(hdev);
2696
2697 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2698 if (!conn)
2699 goto unlock;
2700
Johan Hedberg03b555e2011-01-04 15:40:05 +02002701 conn->remote_cap = ev->capability;
2702 conn->remote_oob = ev->oob_data;
2703 conn->remote_auth = ev->authentication;
2704
2705unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002706 hci_dev_unlock(hdev);
2707}
2708
Johan Hedberga5c29682011-02-19 12:05:57 -03002709static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2710 struct sk_buff *skb)
2711{
2712 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002713 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07002714 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03002715
2716 BT_DBG("%s", hdev->name);
2717
2718 hci_dev_lock(hdev);
2719
Johan Hedberg7a828902011-04-28 11:28:53 -07002720 if (!test_bit(HCI_MGMT, &hdev->flags))
2721 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03002722
Johan Hedberg7a828902011-04-28 11:28:53 -07002723 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2724 if (!conn)
2725 goto unlock;
2726
2727 loc_mitm = (conn->auth_type & 0x01);
2728 rem_mitm = (conn->remote_auth & 0x01);
2729
2730 /* If we require MITM but the remote device can't provide that
2731 * (it has NoInputNoOutput) then reject the confirmation
2732 * request. The only exception is when we're dedicated bonding
2733 * initiators (connect_cfm_cb set) since then we always have the MITM
2734 * bit set. */
2735 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
2736 BT_DBG("Rejecting request: remote device can't provide MITM");
2737 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
2738 sizeof(ev->bdaddr), &ev->bdaddr);
2739 goto unlock;
2740 }
2741
2742 /* If no side requires MITM protection; auto-accept */
2743 if ((!loc_mitm || conn->remote_cap == 0x03) &&
2744 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002745
2746 /* If we're not the initiators request authorization to
2747 * proceed from user space (mgmt_user_confirm with
2748 * confirm_hint set to 1). */
2749 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
2750 BT_DBG("Confirming auto-accept as acceptor");
2751 confirm_hint = 1;
2752 goto confirm;
2753 }
2754
Johan Hedberg9f616562011-04-28 11:28:54 -07002755 BT_DBG("Auto-accept of user confirmation with %ums delay",
2756 hdev->auto_accept_delay);
2757
2758 if (hdev->auto_accept_delay > 0) {
2759 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
2760 mod_timer(&conn->auto_accept_timer, jiffies + delay);
2761 goto unlock;
2762 }
2763
Johan Hedberg7a828902011-04-28 11:28:53 -07002764 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
2765 sizeof(ev->bdaddr), &ev->bdaddr);
2766 goto unlock;
2767 }
2768
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002769confirm:
Johan Hedberg744cf192011-11-08 20:40:14 +02002770 mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002771 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07002772
2773unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03002774 hci_dev_unlock(hdev);
2775}
2776
Marcel Holtmann04936842008-07-14 20:13:48 +02002777static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2778{
2779 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
2780 struct hci_conn *conn;
2781
2782 BT_DBG("%s", hdev->name);
2783
2784 hci_dev_lock(hdev);
2785
2786 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03002787 if (!conn)
2788 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002789
Johan Hedberg2a611692011-02-19 12:06:00 -03002790 /* To avoid duplicate auth_failed events to user space we check
2791 * the HCI_CONN_AUTH_PEND flag which will be set if we
2792 * initiated the authentication. A traditional auth_complete
2793 * event gets always produced as initiator and is also mapped to
2794 * the mgmt_auth_failed event */
2795 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
Johan Hedberg744cf192011-11-08 20:40:14 +02002796 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03002797
2798 hci_conn_put(conn);
2799
2800unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002801 hci_dev_unlock(hdev);
2802}
2803
Marcel Holtmann41a96212008-07-14 20:13:48 +02002804static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2805{
2806 struct hci_ev_remote_host_features *ev = (void *) skb->data;
2807 struct inquiry_entry *ie;
2808
2809 BT_DBG("%s", hdev->name);
2810
2811 hci_dev_lock(hdev);
2812
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002813 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2814 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02002815 ie->data.ssp_mode = (ev->features[0] & 0x01);
2816
2817 hci_dev_unlock(hdev);
2818}
2819
Szymon Janc2763eda2011-03-22 13:12:22 +01002820static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
2821 struct sk_buff *skb)
2822{
2823 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
2824 struct oob_data *data;
2825
2826 BT_DBG("%s", hdev->name);
2827
2828 hci_dev_lock(hdev);
2829
Szymon Jance1ba1f12011-04-06 13:01:59 +02002830 if (!test_bit(HCI_MGMT, &hdev->flags))
2831 goto unlock;
2832
Szymon Janc2763eda2011-03-22 13:12:22 +01002833 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
2834 if (data) {
2835 struct hci_cp_remote_oob_data_reply cp;
2836
2837 bacpy(&cp.bdaddr, &ev->bdaddr);
2838 memcpy(cp.hash, data->hash, sizeof(cp.hash));
2839 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
2840
2841 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
2842 &cp);
2843 } else {
2844 struct hci_cp_remote_oob_data_neg_reply cp;
2845
2846 bacpy(&cp.bdaddr, &ev->bdaddr);
2847 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
2848 &cp);
2849 }
2850
Szymon Jance1ba1f12011-04-06 13:01:59 +02002851unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01002852 hci_dev_unlock(hdev);
2853}
2854
Ville Tervofcd89c02011-02-10 22:38:47 -03002855static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2856{
2857 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2858 struct hci_conn *conn;
2859
2860 BT_DBG("%s status %d", hdev->name, ev->status);
2861
2862 hci_dev_lock(hdev);
2863
2864 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03002865 if (!conn) {
2866 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
2867 if (!conn) {
2868 BT_ERR("No memory for new connection");
2869 hci_dev_unlock(hdev);
2870 return;
2871 }
Andre Guedes29b79882011-05-31 14:20:54 -03002872
2873 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03002874 }
Ville Tervofcd89c02011-02-10 22:38:47 -03002875
2876 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02002877 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
2878 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03002879 hci_proto_connect_cfm(conn, ev->status);
2880 conn->state = BT_CLOSED;
2881 hci_conn_del(conn);
2882 goto unlock;
2883 }
2884
Johan Hedberg48264f02011-11-09 13:58:58 +02002885 mgmt_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03002886
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03002887 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03002888 conn->handle = __le16_to_cpu(ev->handle);
2889 conn->state = BT_CONNECTED;
2890
2891 hci_conn_hold_device(conn);
2892 hci_conn_add_sysfs(conn);
2893
2894 hci_proto_connect_cfm(conn, ev->status);
2895
2896unlock:
2897 hci_dev_unlock(hdev);
2898}
2899
Andre Guedes9aa04c92011-05-26 16:23:51 -03002900static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
2901 struct sk_buff *skb)
2902{
Andre Guedese95beb42011-09-26 20:48:35 -03002903 u8 num_reports = skb->data[0];
2904 void *ptr = &skb->data[1];
Andre Guedes9aa04c92011-05-26 16:23:51 -03002905
2906 hci_dev_lock(hdev);
2907
Andre Guedese95beb42011-09-26 20:48:35 -03002908 while (num_reports--) {
2909 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03002910
Andre Guedes9aa04c92011-05-26 16:23:51 -03002911 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03002912
2913 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03002914 }
2915
2916 hci_dev_unlock(hdev);
2917}
2918
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002919static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
2920 struct sk_buff *skb)
2921{
2922 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
2923 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002924 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002925 struct hci_conn *conn;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002926 struct link_key *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002927
2928 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
2929
2930 hci_dev_lock(hdev);
2931
2932 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002933 if (conn == NULL)
2934 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002935
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002936 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
2937 if (ltk == NULL)
2938 goto not_found;
2939
2940 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002941 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes726b4ff2011-07-08 18:31:45 -03002942 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002943
2944 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
2945
2946 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002947
2948 return;
2949
2950not_found:
2951 neg.handle = ev->handle;
2952 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
2953 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002954}
2955
Ville Tervofcd89c02011-02-10 22:38:47 -03002956static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
2957{
2958 struct hci_ev_le_meta *le_ev = (void *) skb->data;
2959
2960 skb_pull(skb, sizeof(*le_ev));
2961
2962 switch (le_ev->subevent) {
2963 case HCI_EV_LE_CONN_COMPLETE:
2964 hci_le_conn_complete_evt(hdev, skb);
2965 break;
2966
Andre Guedes9aa04c92011-05-26 16:23:51 -03002967 case HCI_EV_LE_ADVERTISING_REPORT:
2968 hci_le_adv_report_evt(hdev, skb);
2969 break;
2970
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002971 case HCI_EV_LE_LTK_REQ:
2972 hci_le_ltk_request_evt(hdev, skb);
2973 break;
2974
Ville Tervofcd89c02011-02-10 22:38:47 -03002975 default:
2976 break;
2977 }
2978}
2979
Linus Torvalds1da177e2005-04-16 15:20:36 -07002980void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
2981{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002982 struct hci_event_hdr *hdr = (void *) skb->data;
2983 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984
2985 skb_pull(skb, HCI_EVENT_HDR_SIZE);
2986
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002987 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988 case HCI_EV_INQUIRY_COMPLETE:
2989 hci_inquiry_complete_evt(hdev, skb);
2990 break;
2991
2992 case HCI_EV_INQUIRY_RESULT:
2993 hci_inquiry_result_evt(hdev, skb);
2994 break;
2995
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002996 case HCI_EV_CONN_COMPLETE:
2997 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02002998 break;
2999
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000 case HCI_EV_CONN_REQUEST:
3001 hci_conn_request_evt(hdev, skb);
3002 break;
3003
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004 case HCI_EV_DISCONN_COMPLETE:
3005 hci_disconn_complete_evt(hdev, skb);
3006 break;
3007
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008 case HCI_EV_AUTH_COMPLETE:
3009 hci_auth_complete_evt(hdev, skb);
3010 break;
3011
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003012 case HCI_EV_REMOTE_NAME:
3013 hci_remote_name_evt(hdev, skb);
3014 break;
3015
Linus Torvalds1da177e2005-04-16 15:20:36 -07003016 case HCI_EV_ENCRYPT_CHANGE:
3017 hci_encrypt_change_evt(hdev, skb);
3018 break;
3019
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003020 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3021 hci_change_link_key_complete_evt(hdev, skb);
3022 break;
3023
3024 case HCI_EV_REMOTE_FEATURES:
3025 hci_remote_features_evt(hdev, skb);
3026 break;
3027
3028 case HCI_EV_REMOTE_VERSION:
3029 hci_remote_version_evt(hdev, skb);
3030 break;
3031
3032 case HCI_EV_QOS_SETUP_COMPLETE:
3033 hci_qos_setup_complete_evt(hdev, skb);
3034 break;
3035
3036 case HCI_EV_CMD_COMPLETE:
3037 hci_cmd_complete_evt(hdev, skb);
3038 break;
3039
3040 case HCI_EV_CMD_STATUS:
3041 hci_cmd_status_evt(hdev, skb);
3042 break;
3043
3044 case HCI_EV_ROLE_CHANGE:
3045 hci_role_change_evt(hdev, skb);
3046 break;
3047
3048 case HCI_EV_NUM_COMP_PKTS:
3049 hci_num_comp_pkts_evt(hdev, skb);
3050 break;
3051
3052 case HCI_EV_MODE_CHANGE:
3053 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003054 break;
3055
3056 case HCI_EV_PIN_CODE_REQ:
3057 hci_pin_code_request_evt(hdev, skb);
3058 break;
3059
3060 case HCI_EV_LINK_KEY_REQ:
3061 hci_link_key_request_evt(hdev, skb);
3062 break;
3063
3064 case HCI_EV_LINK_KEY_NOTIFY:
3065 hci_link_key_notify_evt(hdev, skb);
3066 break;
3067
3068 case HCI_EV_CLOCK_OFFSET:
3069 hci_clock_offset_evt(hdev, skb);
3070 break;
3071
Marcel Holtmanna8746412008-07-14 20:13:46 +02003072 case HCI_EV_PKT_TYPE_CHANGE:
3073 hci_pkt_type_change_evt(hdev, skb);
3074 break;
3075
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003076 case HCI_EV_PSCAN_REP_MODE:
3077 hci_pscan_rep_mode_evt(hdev, skb);
3078 break;
3079
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003080 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3081 hci_inquiry_result_with_rssi_evt(hdev, skb);
3082 break;
3083
3084 case HCI_EV_REMOTE_EXT_FEATURES:
3085 hci_remote_ext_features_evt(hdev, skb);
3086 break;
3087
3088 case HCI_EV_SYNC_CONN_COMPLETE:
3089 hci_sync_conn_complete_evt(hdev, skb);
3090 break;
3091
3092 case HCI_EV_SYNC_CONN_CHANGED:
3093 hci_sync_conn_changed_evt(hdev, skb);
3094 break;
3095
Marcel Holtmann04837f62006-07-03 10:02:33 +02003096 case HCI_EV_SNIFF_SUBRATE:
3097 hci_sniff_subrate_evt(hdev, skb);
3098 break;
3099
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003100 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3101 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003102 break;
3103
Marcel Holtmann04936842008-07-14 20:13:48 +02003104 case HCI_EV_IO_CAPA_REQUEST:
3105 hci_io_capa_request_evt(hdev, skb);
3106 break;
3107
Johan Hedberg03b555e2011-01-04 15:40:05 +02003108 case HCI_EV_IO_CAPA_REPLY:
3109 hci_io_capa_reply_evt(hdev, skb);
3110 break;
3111
Johan Hedberga5c29682011-02-19 12:05:57 -03003112 case HCI_EV_USER_CONFIRM_REQUEST:
3113 hci_user_confirm_request_evt(hdev, skb);
3114 break;
3115
Marcel Holtmann04936842008-07-14 20:13:48 +02003116 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3117 hci_simple_pair_complete_evt(hdev, skb);
3118 break;
3119
Marcel Holtmann41a96212008-07-14 20:13:48 +02003120 case HCI_EV_REMOTE_HOST_FEATURES:
3121 hci_remote_host_features_evt(hdev, skb);
3122 break;
3123
Ville Tervofcd89c02011-02-10 22:38:47 -03003124 case HCI_EV_LE_META:
3125 hci_le_meta_evt(hdev, skb);
3126 break;
3127
Szymon Janc2763eda2011-03-22 13:12:22 +01003128 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3129 hci_remote_oob_data_request_evt(hdev, skb);
3130 break;
3131
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003132 default:
3133 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134 break;
3135 }
3136
3137 kfree_skb(skb);
3138 hdev->stat.evt_rx++;
3139}
3140
3141/* Generate internal stack event */
3142void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3143{
3144 struct hci_event_hdr *hdr;
3145 struct hci_ev_stack_internal *ev;
3146 struct sk_buff *skb;
3147
3148 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3149 if (!skb)
3150 return;
3151
3152 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3153 hdr->evt = HCI_EV_STACK_INTERNAL;
3154 hdr->plen = sizeof(*ev) + dlen;
3155
3156 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3157 ev->type = type;
3158 memcpy(ev->data, data, dlen);
3159
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003160 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003161 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003162
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003163 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003164 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003165 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003166 kfree_skb(skb);
3167}
Andre Guedese6100a22011-06-30 19:20:54 -03003168
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003169module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003170MODULE_PARM_DESC(enable_le, "Enable LE support");