blob: 980da08e253eb8244a8f08c3cefba105b1ed6a85 [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
Brian Gix1143d452011-11-23 08:28:34 -0800934static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
935{
936 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
937
938 BT_DBG("%s status 0x%x", hdev->name, rp->status);
939
940 hci_dev_lock(hdev);
941
942 if (test_bit(HCI_MGMT, &hdev->flags))
943 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr,
944 rp->status);
945
946 hci_dev_unlock(hdev);
947}
948
949static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
950 struct sk_buff *skb)
951{
952 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
953
954 BT_DBG("%s status 0x%x", hdev->name, rp->status);
955
956 hci_dev_lock(hdev);
957
958 if (test_bit(HCI_MGMT, &hdev->flags))
959 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
960 rp->status);
961
962 hci_dev_unlock(hdev);
963}
964
Szymon Jancc35938b2011-03-22 13:12:21 +0100965static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
966 struct sk_buff *skb)
967{
968 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
969
970 BT_DBG("%s status 0x%x", hdev->name, rp->status);
971
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200972 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200973 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100974 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200975 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100976}
977
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300978static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
979 struct sk_buff *skb)
980{
981 struct hci_cp_le_set_scan_enable *cp;
982 __u8 status = *((__u8 *) skb->data);
983
984 BT_DBG("%s status 0x%x", hdev->name, status);
985
986 if (status)
987 return;
988
989 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
990 if (!cp)
991 return;
992
Andre Guedes35815082011-05-26 16:23:53 -0300993 if (cp->enable == 0x01) {
994 del_timer(&hdev->adv_timer);
Andre Guedesa8f13c82011-09-09 18:56:24 -0300995
996 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300997 hci_adv_entries_clear(hdev);
Andre Guedesa8f13c82011-09-09 18:56:24 -0300998 hci_dev_unlock(hdev);
Andre Guedes35815082011-05-26 16:23:53 -0300999 } else if (cp->enable == 0x00) {
1000 mod_timer(&hdev->adv_timer, jiffies + ADV_CLEAR_TIMEOUT);
1001 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001002}
1003
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001004static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1005{
1006 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1007
1008 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1009
1010 if (rp->status)
1011 return;
1012
1013 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1014}
1015
1016static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1017{
1018 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1019
1020 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1021
1022 if (rp->status)
1023 return;
1024
1025 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1026}
1027
Andre Guedesf9b49302011-06-30 19:20:53 -03001028static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1029 struct sk_buff *skb)
1030{
1031 struct hci_cp_read_local_ext_features cp;
1032 __u8 status = *((__u8 *) skb->data);
1033
1034 BT_DBG("%s status 0x%x", hdev->name, status);
1035
1036 if (status)
1037 return;
1038
1039 cp.page = 0x01;
1040 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1041}
1042
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001043static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1044{
1045 BT_DBG("%s status 0x%x", hdev->name, status);
1046
1047 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001048 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001049 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001050 hci_dev_lock(hdev);
Johan Hedberg164a6e72011-11-01 17:06:44 +02001051 if (test_bit(HCI_MGMT, &hdev->flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001052 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001053 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001054 return;
1055 }
1056
Andre Guedes89352e72011-11-04 14:16:53 -03001057 set_bit(HCI_INQUIRY, &hdev->flags);
1058
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001059 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001060 mgmt_discovering(hdev, 1);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001061 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001062}
1063
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1065{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001066 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001069 BT_DBG("%s status 0x%x", hdev->name, status);
1070
1071 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 if (!cp)
1073 return;
1074
1075 hci_dev_lock(hdev);
1076
1077 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1078
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001079 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080
1081 if (status) {
1082 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001083 if (status != 0x0c || conn->attempt > 2) {
1084 conn->state = BT_CLOSED;
1085 hci_proto_connect_cfm(conn, status);
1086 hci_conn_del(conn);
1087 } else
1088 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 }
1090 } else {
1091 if (!conn) {
1092 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1093 if (conn) {
1094 conn->out = 1;
1095 conn->link_mode |= HCI_LM_MASTER;
1096 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001097 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098 }
1099 }
1100
1101 hci_dev_unlock(hdev);
1102}
1103
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001104static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001106 struct hci_cp_add_sco *cp;
1107 struct hci_conn *acl, *sco;
1108 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001110 BT_DBG("%s status 0x%x", hdev->name, status);
1111
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001112 if (!status)
1113 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001115 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1116 if (!cp)
1117 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001119 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001121 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001122
1123 hci_dev_lock(hdev);
1124
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001125 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001126 if (acl) {
1127 sco = acl->link;
1128 if (sco) {
1129 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001130
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001131 hci_proto_connect_cfm(sco, status);
1132 hci_conn_del(sco);
1133 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001134 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001135
1136 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137}
1138
Marcel Holtmannf8558552008-07-14 20:13:49 +02001139static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1140{
1141 struct hci_cp_auth_requested *cp;
1142 struct hci_conn *conn;
1143
1144 BT_DBG("%s status 0x%x", hdev->name, status);
1145
1146 if (!status)
1147 return;
1148
1149 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1150 if (!cp)
1151 return;
1152
1153 hci_dev_lock(hdev);
1154
1155 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1156 if (conn) {
1157 if (conn->state == BT_CONFIG) {
1158 hci_proto_connect_cfm(conn, status);
1159 hci_conn_put(conn);
1160 }
1161 }
1162
1163 hci_dev_unlock(hdev);
1164}
1165
1166static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1167{
1168 struct hci_cp_set_conn_encrypt *cp;
1169 struct hci_conn *conn;
1170
1171 BT_DBG("%s status 0x%x", hdev->name, status);
1172
1173 if (!status)
1174 return;
1175
1176 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1177 if (!cp)
1178 return;
1179
1180 hci_dev_lock(hdev);
1181
1182 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1183 if (conn) {
1184 if (conn->state == BT_CONFIG) {
1185 hci_proto_connect_cfm(conn, status);
1186 hci_conn_put(conn);
1187 }
1188 }
1189
1190 hci_dev_unlock(hdev);
1191}
1192
Johan Hedberg127178d2010-11-18 22:22:29 +02001193static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001194 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001195{
Johan Hedberg392599b2010-11-18 22:22:28 +02001196 if (conn->state != BT_CONFIG || !conn->out)
1197 return 0;
1198
Johan Hedberg765c2a92011-01-19 12:06:52 +05301199 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001200 return 0;
1201
1202 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001203 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedberg392599b2010-11-18 22:22:28 +02001204 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001205 conn->pending_sec_level != BT_SECURITY_HIGH &&
1206 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001207 return 0;
1208
Johan Hedberg392599b2010-11-18 22:22:28 +02001209 return 1;
1210}
1211
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001212static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1213{
Johan Hedberg127178d2010-11-18 22:22:29 +02001214 struct hci_cp_remote_name_req *cp;
1215 struct hci_conn *conn;
1216
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001217 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001218
1219 /* If successful wait for the name req complete event before
1220 * checking for the need to do authentication */
1221 if (!status)
1222 return;
1223
1224 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1225 if (!cp)
1226 return;
1227
1228 hci_dev_lock(hdev);
1229
1230 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001231 if (!conn)
1232 goto unlock;
1233
1234 if (!hci_outgoing_auth_needed(hdev, conn))
1235 goto unlock;
1236
1237 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001238 struct hci_cp_auth_requested cp;
1239 cp.handle = __cpu_to_le16(conn->handle);
1240 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1241 }
1242
Johan Hedberg79c6c702011-04-28 11:28:55 -07001243unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001244 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001245}
1246
Marcel Holtmann769be972008-07-14 20:13:49 +02001247static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1248{
1249 struct hci_cp_read_remote_features *cp;
1250 struct hci_conn *conn;
1251
1252 BT_DBG("%s status 0x%x", hdev->name, status);
1253
1254 if (!status)
1255 return;
1256
1257 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1258 if (!cp)
1259 return;
1260
1261 hci_dev_lock(hdev);
1262
1263 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1264 if (conn) {
1265 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001266 hci_proto_connect_cfm(conn, status);
1267 hci_conn_put(conn);
1268 }
1269 }
1270
1271 hci_dev_unlock(hdev);
1272}
1273
1274static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1275{
1276 struct hci_cp_read_remote_ext_features *cp;
1277 struct hci_conn *conn;
1278
1279 BT_DBG("%s status 0x%x", hdev->name, status);
1280
1281 if (!status)
1282 return;
1283
1284 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1285 if (!cp)
1286 return;
1287
1288 hci_dev_lock(hdev);
1289
1290 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1291 if (conn) {
1292 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001293 hci_proto_connect_cfm(conn, status);
1294 hci_conn_put(conn);
1295 }
1296 }
1297
1298 hci_dev_unlock(hdev);
1299}
1300
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001301static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1302{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001303 struct hci_cp_setup_sync_conn *cp;
1304 struct hci_conn *acl, *sco;
1305 __u16 handle;
1306
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001307 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001308
1309 if (!status)
1310 return;
1311
1312 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1313 if (!cp)
1314 return;
1315
1316 handle = __le16_to_cpu(cp->handle);
1317
1318 BT_DBG("%s handle %d", hdev->name, handle);
1319
1320 hci_dev_lock(hdev);
1321
1322 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001323 if (acl) {
1324 sco = acl->link;
1325 if (sco) {
1326 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001327
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001328 hci_proto_connect_cfm(sco, status);
1329 hci_conn_del(sco);
1330 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001331 }
1332
1333 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001334}
1335
1336static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1337{
1338 struct hci_cp_sniff_mode *cp;
1339 struct hci_conn *conn;
1340
1341 BT_DBG("%s status 0x%x", hdev->name, status);
1342
1343 if (!status)
1344 return;
1345
1346 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1347 if (!cp)
1348 return;
1349
1350 hci_dev_lock(hdev);
1351
1352 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001353 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001354 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1355
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001356 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1357 hci_sco_setup(conn, status);
1358 }
1359
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001360 hci_dev_unlock(hdev);
1361}
1362
1363static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1364{
1365 struct hci_cp_exit_sniff_mode *cp;
1366 struct hci_conn *conn;
1367
1368 BT_DBG("%s status 0x%x", hdev->name, status);
1369
1370 if (!status)
1371 return;
1372
1373 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1374 if (!cp)
1375 return;
1376
1377 hci_dev_lock(hdev);
1378
1379 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001380 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001381 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1382
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001383 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1384 hci_sco_setup(conn, status);
1385 }
1386
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001387 hci_dev_unlock(hdev);
1388}
1389
Ville Tervofcd89c02011-02-10 22:38:47 -03001390static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1391{
1392 struct hci_cp_le_create_conn *cp;
1393 struct hci_conn *conn;
1394
1395 BT_DBG("%s status 0x%x", hdev->name, status);
1396
1397 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1398 if (!cp)
1399 return;
1400
1401 hci_dev_lock(hdev);
1402
1403 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1404
1405 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1406 conn);
1407
1408 if (status) {
1409 if (conn && conn->state == BT_CONNECT) {
1410 conn->state = BT_CLOSED;
1411 hci_proto_connect_cfm(conn, status);
1412 hci_conn_del(conn);
1413 }
1414 } else {
1415 if (!conn) {
1416 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001417 if (conn) {
1418 conn->dst_type = cp->peer_addr_type;
Ville Tervofcd89c02011-02-10 22:38:47 -03001419 conn->out = 1;
Andre Guedes29b79882011-05-31 14:20:54 -03001420 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001421 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001422 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001423 }
1424 }
1425
1426 hci_dev_unlock(hdev);
1427}
1428
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001429static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1430{
1431 BT_DBG("%s status 0x%x", hdev->name, status);
1432}
1433
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001434static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1435{
1436 __u8 status = *((__u8 *) skb->data);
1437
1438 BT_DBG("%s status %d", hdev->name, status);
1439
Johan Hedberg23bb5762010-12-21 23:01:27 +02001440 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001441
1442 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001443
1444 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1445 return;
1446
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001447 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001448 mgmt_discovering(hdev, 0);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001449 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001450}
1451
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1453{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001454 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001455 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456 int num_rsp = *((__u8 *) skb->data);
1457
1458 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1459
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001460 if (!num_rsp)
1461 return;
1462
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001464
Johan Hedberge17acd42011-03-30 23:57:16 +03001465 for (; num_rsp; num_rsp--, info++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 bacpy(&data.bdaddr, &info->bdaddr);
1467 data.pscan_rep_mode = info->pscan_rep_mode;
1468 data.pscan_period_mode = info->pscan_period_mode;
1469 data.pscan_mode = info->pscan_mode;
1470 memcpy(data.dev_class, info->dev_class, 3);
1471 data.clock_offset = info->clock_offset;
1472 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001473 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02001475 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg4c659c32011-11-07 23:13:39 +02001476 info->dev_class, 0, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001478
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479 hci_dev_unlock(hdev);
1480}
1481
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001482static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001484 struct hci_ev_conn_complete *ev = (void *) skb->data;
1485 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001487 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001488
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001490
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001491 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001492 if (!conn) {
1493 if (ev->link_type != SCO_LINK)
1494 goto unlock;
1495
1496 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1497 if (!conn)
1498 goto unlock;
1499
1500 conn->type = SCO_LINK;
1501 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001502
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001503 if (!ev->status) {
1504 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001505
1506 if (conn->type == ACL_LINK) {
1507 conn->state = BT_CONFIG;
1508 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001509 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg48264f02011-11-09 13:58:58 +02001510 mgmt_connected(hdev, &ev->bdaddr, conn->type,
1511 conn->dst_type);
Marcel Holtmann769be972008-07-14 20:13:49 +02001512 } else
1513 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001514
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001515 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001516 hci_conn_add_sysfs(conn);
1517
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001518 if (test_bit(HCI_AUTH, &hdev->flags))
1519 conn->link_mode |= HCI_LM_AUTH;
1520
1521 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1522 conn->link_mode |= HCI_LM_ENCRYPT;
1523
1524 /* Get remote features */
1525 if (conn->type == ACL_LINK) {
1526 struct hci_cp_read_remote_features cp;
1527 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001528 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1529 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001530 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001531
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001532 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +02001533 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001534 struct hci_cp_change_conn_ptype cp;
1535 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001536 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1537 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1538 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001539 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001540 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001541 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001542 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001543 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001544 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001545 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001546
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001547 if (conn->type == ACL_LINK)
1548 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001549
Marcel Holtmann769be972008-07-14 20:13:49 +02001550 if (ev->status) {
1551 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001552 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001553 } else if (ev->link_type != ACL_LINK)
1554 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001555
1556unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001558
1559 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560}
1561
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1563{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001564 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565 int mask = hdev->link_mode;
1566
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001567 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1568 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569
1570 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1571
Szymon Janc138d22e2011-02-17 16:44:23 +01001572 if ((mask & HCI_LM_ACCEPT) &&
1573 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001575 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577
1578 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001579
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001580 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1581 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001582 memcpy(ie->data.dev_class, ev->dev_class, 3);
1583
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1585 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001586 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1587 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001588 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 hci_dev_unlock(hdev);
1590 return;
1591 }
1592 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001593
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 memcpy(conn->dev_class, ev->dev_class, 3);
1595 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001596
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 hci_dev_unlock(hdev);
1598
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001599 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1600 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001602 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001604 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1605 cp.role = 0x00; /* Become master */
1606 else
1607 cp.role = 0x01; /* Remain slave */
1608
1609 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1610 sizeof(cp), &cp);
1611 } else {
1612 struct hci_cp_accept_sync_conn_req cp;
1613
1614 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001615 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001616
1617 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1618 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1619 cp.max_latency = cpu_to_le16(0xffff);
1620 cp.content_format = cpu_to_le16(hdev->voice_setting);
1621 cp.retrans_effort = 0xff;
1622
1623 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1624 sizeof(cp), &cp);
1625 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626 } else {
1627 /* Connection rejected */
1628 struct hci_cp_reject_conn_req cp;
1629
1630 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001631 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001632 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633 }
1634}
1635
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1637{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001638 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001639 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640
1641 BT_DBG("%s status %d", hdev->name, ev->status);
1642
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643 hci_dev_lock(hdev);
1644
Marcel Holtmann04837f62006-07-03 10:02:33 +02001645 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001646 if (!conn)
1647 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001648
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001649 if (ev->status == 0)
1650 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001652 if (conn->type == ACL_LINK || conn->type == LE_LINK) {
1653 if (ev->status != 0)
1654 mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
1655 else
1656 mgmt_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001657 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001658 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001659
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001660 if (ev->status == 0) {
1661 hci_proto_disconn_cfm(conn, ev->reason);
1662 hci_conn_del(conn);
1663 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001664
1665unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 hci_dev_unlock(hdev);
1667}
1668
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001669static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1670{
1671 struct hci_ev_auth_complete *ev = (void *) skb->data;
1672 struct hci_conn *conn;
1673
1674 BT_DBG("%s status %d", hdev->name, ev->status);
1675
1676 hci_dev_lock(hdev);
1677
1678 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001679 if (!conn)
1680 goto unlock;
1681
1682 if (!ev->status) {
1683 if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) &&
1684 test_bit(HCI_CONN_REAUTH_PEND, &conn->pend)) {
1685 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001686 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001687 conn->link_mode |= HCI_LM_AUTH;
1688 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001689 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001690 } else {
Johan Hedberg744cf192011-11-08 20:40:14 +02001691 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001692 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001693
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001694 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1695 clear_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001696
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001697 if (conn->state == BT_CONFIG) {
1698 if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) {
1699 struct hci_cp_set_conn_encrypt cp;
1700 cp.handle = ev->handle;
1701 cp.encrypt = 0x01;
1702 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1703 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001704 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001705 conn->state = BT_CONNECTED;
1706 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001707 hci_conn_put(conn);
1708 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001709 } else {
1710 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001711
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001712 hci_conn_hold(conn);
1713 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1714 hci_conn_put(conn);
1715 }
1716
1717 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1718 if (!ev->status) {
1719 struct hci_cp_set_conn_encrypt cp;
1720 cp.handle = ev->handle;
1721 cp.encrypt = 0x01;
1722 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1723 &cp);
1724 } else {
1725 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1726 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001727 }
1728 }
1729
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001730unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001731 hci_dev_unlock(hdev);
1732}
1733
1734static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1735{
Johan Hedberg127178d2010-11-18 22:22:29 +02001736 struct hci_ev_remote_name *ev = (void *) skb->data;
1737 struct hci_conn *conn;
1738
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001739 BT_DBG("%s", hdev->name);
1740
1741 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001742
1743 hci_dev_lock(hdev);
1744
Johan Hedberga88a9652011-03-30 13:18:12 +03001745 if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001746 mgmt_remote_name(hdev, &ev->bdaddr, ev->name);
Johan Hedberga88a9652011-03-30 13:18:12 +03001747
Johan Hedberg127178d2010-11-18 22:22:29 +02001748 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001749 if (!conn)
1750 goto unlock;
1751
1752 if (!hci_outgoing_auth_needed(hdev, conn))
1753 goto unlock;
1754
1755 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001756 struct hci_cp_auth_requested cp;
1757 cp.handle = __cpu_to_le16(conn->handle);
1758 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1759 }
1760
Johan Hedberg79c6c702011-04-28 11:28:55 -07001761unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001762 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001763}
1764
1765static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1766{
1767 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1768 struct hci_conn *conn;
1769
1770 BT_DBG("%s status %d", hdev->name, ev->status);
1771
1772 hci_dev_lock(hdev);
1773
1774 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1775 if (conn) {
1776 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001777 if (ev->encrypt) {
1778 /* Encryption implies authentication */
1779 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001780 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001781 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001782 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001783 conn->link_mode &= ~HCI_LM_ENCRYPT;
1784 }
1785
1786 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1787
Marcel Holtmannf8558552008-07-14 20:13:49 +02001788 if (conn->state == BT_CONFIG) {
1789 if (!ev->status)
1790 conn->state = BT_CONNECTED;
1791
1792 hci_proto_connect_cfm(conn, ev->status);
1793 hci_conn_put(conn);
1794 } else
1795 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001796 }
1797
1798 hci_dev_unlock(hdev);
1799}
1800
1801static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1802{
1803 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1804 struct hci_conn *conn;
1805
1806 BT_DBG("%s status %d", hdev->name, ev->status);
1807
1808 hci_dev_lock(hdev);
1809
1810 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1811 if (conn) {
1812 if (!ev->status)
1813 conn->link_mode |= HCI_LM_SECURE;
1814
1815 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1816
1817 hci_key_change_cfm(conn, ev->status);
1818 }
1819
1820 hci_dev_unlock(hdev);
1821}
1822
1823static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1824{
1825 struct hci_ev_remote_features *ev = (void *) skb->data;
1826 struct hci_conn *conn;
1827
1828 BT_DBG("%s status %d", hdev->name, ev->status);
1829
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001830 hci_dev_lock(hdev);
1831
1832 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001833 if (!conn)
1834 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001835
Johan Hedbergccd556f2010-11-10 17:11:51 +02001836 if (!ev->status)
1837 memcpy(conn->features, ev->features, 8);
1838
1839 if (conn->state != BT_CONFIG)
1840 goto unlock;
1841
1842 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1843 struct hci_cp_read_remote_ext_features cp;
1844 cp.handle = ev->handle;
1845 cp.page = 0x01;
1846 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001847 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001848 goto unlock;
1849 }
1850
Johan Hedberg127178d2010-11-18 22:22:29 +02001851 if (!ev->status) {
1852 struct hci_cp_remote_name_req cp;
1853 memset(&cp, 0, sizeof(cp));
1854 bacpy(&cp.bdaddr, &conn->dst);
1855 cp.pscan_rep_mode = 0x02;
1856 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1857 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001858
Johan Hedberg127178d2010-11-18 22:22:29 +02001859 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001860 conn->state = BT_CONNECTED;
1861 hci_proto_connect_cfm(conn, ev->status);
1862 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001863 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001864
Johan Hedbergccd556f2010-11-10 17:11:51 +02001865unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001866 hci_dev_unlock(hdev);
1867}
1868
1869static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1870{
1871 BT_DBG("%s", hdev->name);
1872}
1873
1874static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1875{
1876 BT_DBG("%s", hdev->name);
1877}
1878
1879static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1880{
1881 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1882 __u16 opcode;
1883
1884 skb_pull(skb, sizeof(*ev));
1885
1886 opcode = __le16_to_cpu(ev->opcode);
1887
1888 switch (opcode) {
1889 case HCI_OP_INQUIRY_CANCEL:
1890 hci_cc_inquiry_cancel(hdev, skb);
1891 break;
1892
1893 case HCI_OP_EXIT_PERIODIC_INQ:
1894 hci_cc_exit_periodic_inq(hdev, skb);
1895 break;
1896
1897 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1898 hci_cc_remote_name_req_cancel(hdev, skb);
1899 break;
1900
1901 case HCI_OP_ROLE_DISCOVERY:
1902 hci_cc_role_discovery(hdev, skb);
1903 break;
1904
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001905 case HCI_OP_READ_LINK_POLICY:
1906 hci_cc_read_link_policy(hdev, skb);
1907 break;
1908
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001909 case HCI_OP_WRITE_LINK_POLICY:
1910 hci_cc_write_link_policy(hdev, skb);
1911 break;
1912
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001913 case HCI_OP_READ_DEF_LINK_POLICY:
1914 hci_cc_read_def_link_policy(hdev, skb);
1915 break;
1916
1917 case HCI_OP_WRITE_DEF_LINK_POLICY:
1918 hci_cc_write_def_link_policy(hdev, skb);
1919 break;
1920
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001921 case HCI_OP_RESET:
1922 hci_cc_reset(hdev, skb);
1923 break;
1924
1925 case HCI_OP_WRITE_LOCAL_NAME:
1926 hci_cc_write_local_name(hdev, skb);
1927 break;
1928
1929 case HCI_OP_READ_LOCAL_NAME:
1930 hci_cc_read_local_name(hdev, skb);
1931 break;
1932
1933 case HCI_OP_WRITE_AUTH_ENABLE:
1934 hci_cc_write_auth_enable(hdev, skb);
1935 break;
1936
1937 case HCI_OP_WRITE_ENCRYPT_MODE:
1938 hci_cc_write_encrypt_mode(hdev, skb);
1939 break;
1940
1941 case HCI_OP_WRITE_SCAN_ENABLE:
1942 hci_cc_write_scan_enable(hdev, skb);
1943 break;
1944
1945 case HCI_OP_READ_CLASS_OF_DEV:
1946 hci_cc_read_class_of_dev(hdev, skb);
1947 break;
1948
1949 case HCI_OP_WRITE_CLASS_OF_DEV:
1950 hci_cc_write_class_of_dev(hdev, skb);
1951 break;
1952
1953 case HCI_OP_READ_VOICE_SETTING:
1954 hci_cc_read_voice_setting(hdev, skb);
1955 break;
1956
1957 case HCI_OP_WRITE_VOICE_SETTING:
1958 hci_cc_write_voice_setting(hdev, skb);
1959 break;
1960
1961 case HCI_OP_HOST_BUFFER_SIZE:
1962 hci_cc_host_buffer_size(hdev, skb);
1963 break;
1964
Marcel Holtmann333140b2008-07-14 20:13:48 +02001965 case HCI_OP_READ_SSP_MODE:
1966 hci_cc_read_ssp_mode(hdev, skb);
1967 break;
1968
1969 case HCI_OP_WRITE_SSP_MODE:
1970 hci_cc_write_ssp_mode(hdev, skb);
1971 break;
1972
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001973 case HCI_OP_READ_LOCAL_VERSION:
1974 hci_cc_read_local_version(hdev, skb);
1975 break;
1976
1977 case HCI_OP_READ_LOCAL_COMMANDS:
1978 hci_cc_read_local_commands(hdev, skb);
1979 break;
1980
1981 case HCI_OP_READ_LOCAL_FEATURES:
1982 hci_cc_read_local_features(hdev, skb);
1983 break;
1984
Andre Guedes971e3a42011-06-30 19:20:52 -03001985 case HCI_OP_READ_LOCAL_EXT_FEATURES:
1986 hci_cc_read_local_ext_features(hdev, skb);
1987 break;
1988
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001989 case HCI_OP_READ_BUFFER_SIZE:
1990 hci_cc_read_buffer_size(hdev, skb);
1991 break;
1992
1993 case HCI_OP_READ_BD_ADDR:
1994 hci_cc_read_bd_addr(hdev, skb);
1995 break;
1996
Johan Hedberg23bb5762010-12-21 23:01:27 +02001997 case HCI_OP_WRITE_CA_TIMEOUT:
1998 hci_cc_write_ca_timeout(hdev, skb);
1999 break;
2000
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002001 case HCI_OP_READ_LOCAL_AMP_INFO:
2002 hci_cc_read_local_amp_info(hdev, skb);
2003 break;
2004
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002005 case HCI_OP_DELETE_STORED_LINK_KEY:
2006 hci_cc_delete_stored_link_key(hdev, skb);
2007 break;
2008
Johan Hedbergd5859e22011-01-25 01:19:58 +02002009 case HCI_OP_SET_EVENT_MASK:
2010 hci_cc_set_event_mask(hdev, skb);
2011 break;
2012
2013 case HCI_OP_WRITE_INQUIRY_MODE:
2014 hci_cc_write_inquiry_mode(hdev, skb);
2015 break;
2016
2017 case HCI_OP_READ_INQ_RSP_TX_POWER:
2018 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2019 break;
2020
2021 case HCI_OP_SET_EVENT_FLT:
2022 hci_cc_set_event_flt(hdev, skb);
2023 break;
2024
Johan Hedberg980e1a52011-01-22 06:10:07 +02002025 case HCI_OP_PIN_CODE_REPLY:
2026 hci_cc_pin_code_reply(hdev, skb);
2027 break;
2028
2029 case HCI_OP_PIN_CODE_NEG_REPLY:
2030 hci_cc_pin_code_neg_reply(hdev, skb);
2031 break;
2032
Szymon Jancc35938b2011-03-22 13:12:21 +01002033 case HCI_OP_READ_LOCAL_OOB_DATA:
2034 hci_cc_read_local_oob_data_reply(hdev, skb);
2035 break;
2036
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002037 case HCI_OP_LE_READ_BUFFER_SIZE:
2038 hci_cc_le_read_buffer_size(hdev, skb);
2039 break;
2040
Johan Hedberga5c29682011-02-19 12:05:57 -03002041 case HCI_OP_USER_CONFIRM_REPLY:
2042 hci_cc_user_confirm_reply(hdev, skb);
2043 break;
2044
2045 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2046 hci_cc_user_confirm_neg_reply(hdev, skb);
2047 break;
2048
Brian Gix1143d452011-11-23 08:28:34 -08002049 case HCI_OP_USER_PASSKEY_REPLY:
2050 hci_cc_user_passkey_reply(hdev, skb);
2051 break;
2052
2053 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2054 hci_cc_user_passkey_neg_reply(hdev, skb);
2055 break;
2056
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002057 case HCI_OP_LE_SET_SCAN_ENABLE:
2058 hci_cc_le_set_scan_enable(hdev, skb);
2059 break;
2060
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002061 case HCI_OP_LE_LTK_REPLY:
2062 hci_cc_le_ltk_reply(hdev, skb);
2063 break;
2064
2065 case HCI_OP_LE_LTK_NEG_REPLY:
2066 hci_cc_le_ltk_neg_reply(hdev, skb);
2067 break;
2068
Andre Guedesf9b49302011-06-30 19:20:53 -03002069 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2070 hci_cc_write_le_host_supported(hdev, skb);
2071 break;
2072
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002073 default:
2074 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2075 break;
2076 }
2077
Ville Tervo6bd32322011-02-16 16:32:41 +02002078 if (ev->opcode != HCI_OP_NOP)
2079 del_timer(&hdev->cmd_timer);
2080
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002081 if (ev->ncmd) {
2082 atomic_set(&hdev->cmd_cnt, 1);
2083 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002084 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002085 }
2086}
2087
2088static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2089{
2090 struct hci_ev_cmd_status *ev = (void *) skb->data;
2091 __u16 opcode;
2092
2093 skb_pull(skb, sizeof(*ev));
2094
2095 opcode = __le16_to_cpu(ev->opcode);
2096
2097 switch (opcode) {
2098 case HCI_OP_INQUIRY:
2099 hci_cs_inquiry(hdev, ev->status);
2100 break;
2101
2102 case HCI_OP_CREATE_CONN:
2103 hci_cs_create_conn(hdev, ev->status);
2104 break;
2105
2106 case HCI_OP_ADD_SCO:
2107 hci_cs_add_sco(hdev, ev->status);
2108 break;
2109
Marcel Holtmannf8558552008-07-14 20:13:49 +02002110 case HCI_OP_AUTH_REQUESTED:
2111 hci_cs_auth_requested(hdev, ev->status);
2112 break;
2113
2114 case HCI_OP_SET_CONN_ENCRYPT:
2115 hci_cs_set_conn_encrypt(hdev, ev->status);
2116 break;
2117
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002118 case HCI_OP_REMOTE_NAME_REQ:
2119 hci_cs_remote_name_req(hdev, ev->status);
2120 break;
2121
Marcel Holtmann769be972008-07-14 20:13:49 +02002122 case HCI_OP_READ_REMOTE_FEATURES:
2123 hci_cs_read_remote_features(hdev, ev->status);
2124 break;
2125
2126 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2127 hci_cs_read_remote_ext_features(hdev, ev->status);
2128 break;
2129
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002130 case HCI_OP_SETUP_SYNC_CONN:
2131 hci_cs_setup_sync_conn(hdev, ev->status);
2132 break;
2133
2134 case HCI_OP_SNIFF_MODE:
2135 hci_cs_sniff_mode(hdev, ev->status);
2136 break;
2137
2138 case HCI_OP_EXIT_SNIFF_MODE:
2139 hci_cs_exit_sniff_mode(hdev, ev->status);
2140 break;
2141
Johan Hedberg8962ee72011-01-20 12:40:27 +02002142 case HCI_OP_DISCONNECT:
2143 if (ev->status != 0)
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002144 mgmt_disconnect_failed(hdev, NULL, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002145 break;
2146
Ville Tervofcd89c02011-02-10 22:38:47 -03002147 case HCI_OP_LE_CREATE_CONN:
2148 hci_cs_le_create_conn(hdev, ev->status);
2149 break;
2150
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002151 case HCI_OP_LE_START_ENC:
2152 hci_cs_le_start_enc(hdev, ev->status);
2153 break;
2154
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002155 default:
2156 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2157 break;
2158 }
2159
Ville Tervo6bd32322011-02-16 16:32:41 +02002160 if (ev->opcode != HCI_OP_NOP)
2161 del_timer(&hdev->cmd_timer);
2162
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002163 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002164 atomic_set(&hdev->cmd_cnt, 1);
2165 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002166 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002167 }
2168}
2169
2170static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2171{
2172 struct hci_ev_role_change *ev = (void *) skb->data;
2173 struct hci_conn *conn;
2174
2175 BT_DBG("%s status %d", hdev->name, ev->status);
2176
2177 hci_dev_lock(hdev);
2178
2179 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2180 if (conn) {
2181 if (!ev->status) {
2182 if (ev->role)
2183 conn->link_mode &= ~HCI_LM_MASTER;
2184 else
2185 conn->link_mode |= HCI_LM_MASTER;
2186 }
2187
2188 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
2189
2190 hci_role_switch_cfm(conn, ev->status, ev->role);
2191 }
2192
2193 hci_dev_unlock(hdev);
2194}
2195
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2197{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002198 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002199 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002200 int i;
2201
2202 skb_pull(skb, sizeof(*ev));
2203
2204 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2205
2206 if (skb->len < ev->num_hndl * 4) {
2207 BT_DBG("%s bad parameters", hdev->name);
2208 return;
2209 }
2210
2211 tasklet_disable(&hdev->tx_task);
2212
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002213 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214 struct hci_conn *conn;
2215 __u16 handle, count;
2216
Harvey Harrison83985312008-05-02 16:25:46 -07002217 handle = get_unaligned_le16(ptr++);
2218 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219
2220 conn = hci_conn_hash_lookup_handle(hdev, handle);
2221 if (conn) {
2222 conn->sent -= count;
2223
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002224 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002225 hdev->acl_cnt += count;
2226 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227 hdev->acl_cnt = hdev->acl_pkts;
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002228 } else if (conn->type == LE_LINK) {
2229 if (hdev->le_pkts) {
2230 hdev->le_cnt += count;
2231 if (hdev->le_cnt > hdev->le_pkts)
2232 hdev->le_cnt = hdev->le_pkts;
2233 } else {
2234 hdev->acl_cnt += count;
2235 if (hdev->acl_cnt > hdev->acl_pkts)
2236 hdev->acl_cnt = hdev->acl_pkts;
2237 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002238 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002239 hdev->sco_cnt += count;
2240 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002241 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242 }
2243 }
2244 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002245
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002246 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247
2248 tasklet_enable(&hdev->tx_task);
2249}
2250
Marcel Holtmann04837f62006-07-03 10:02:33 +02002251static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002253 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002254 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255
2256 BT_DBG("%s status %d", hdev->name, ev->status);
2257
2258 hci_dev_lock(hdev);
2259
Marcel Holtmann04837f62006-07-03 10:02:33 +02002260 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2261 if (conn) {
2262 conn->mode = ev->mode;
2263 conn->interval = __le16_to_cpu(ev->interval);
2264
2265 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
2266 if (conn->mode == HCI_CM_ACTIVE)
2267 conn->power_save = 1;
2268 else
2269 conn->power_save = 0;
2270 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002271
2272 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
2273 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002274 }
2275
2276 hci_dev_unlock(hdev);
2277}
2278
Linus Torvalds1da177e2005-04-16 15:20:36 -07002279static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2280{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002281 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2282 struct hci_conn *conn;
2283
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002284 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002285
2286 hci_dev_lock(hdev);
2287
2288 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002289 if (!conn)
2290 goto unlock;
2291
2292 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002293 hci_conn_hold(conn);
2294 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2295 hci_conn_put(conn);
2296 }
2297
Johan Hedberg03b555e2011-01-04 15:40:05 +02002298 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
2299 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2300 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg582fbe92011-04-28 11:28:58 -07002301 else if (test_bit(HCI_MGMT, &hdev->flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002302 u8 secure;
2303
2304 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2305 secure = 1;
2306 else
2307 secure = 0;
2308
Johan Hedberg744cf192011-11-08 20:40:14 +02002309 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002310 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002311
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002312unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002313 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314}
2315
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2317{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002318 struct hci_ev_link_key_req *ev = (void *) skb->data;
2319 struct hci_cp_link_key_reply cp;
2320 struct hci_conn *conn;
2321 struct link_key *key;
2322
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002323 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002324
2325 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
2326 return;
2327
2328 hci_dev_lock(hdev);
2329
2330 key = hci_find_link_key(hdev, &ev->bdaddr);
2331 if (!key) {
2332 BT_DBG("%s link key not found for %s", hdev->name,
2333 batostr(&ev->bdaddr));
2334 goto not_found;
2335 }
2336
2337 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2338 batostr(&ev->bdaddr));
2339
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002340 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) &&
2341 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002342 BT_DBG("%s ignoring debug key", hdev->name);
2343 goto not_found;
2344 }
2345
2346 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002347 if (conn) {
2348 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2349 conn->auth_type != 0xff &&
2350 (conn->auth_type & 0x01)) {
2351 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2352 goto not_found;
2353 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002354
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002355 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2356 conn->pending_sec_level == BT_SECURITY_HIGH) {
2357 BT_DBG("%s ignoring key unauthenticated for high \
2358 security", hdev->name);
2359 goto not_found;
2360 }
2361
2362 conn->key_type = key->type;
2363 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002364 }
2365
2366 bacpy(&cp.bdaddr, &ev->bdaddr);
2367 memcpy(cp.link_key, key->val, 16);
2368
2369 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2370
2371 hci_dev_unlock(hdev);
2372
2373 return;
2374
2375not_found:
2376 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2377 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002378}
2379
Linus Torvalds1da177e2005-04-16 15:20:36 -07002380static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2381{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002382 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2383 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002384 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002385
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002386 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002387
2388 hci_dev_lock(hdev);
2389
2390 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2391 if (conn) {
2392 hci_conn_hold(conn);
2393 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002394 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002395
2396 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2397 conn->key_type = ev->key_type;
2398
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002399 hci_conn_put(conn);
2400 }
2401
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002402 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002403 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002404 ev->key_type, pin_len);
2405
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002406 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002407}
2408
Marcel Holtmann04837f62006-07-03 10:02:33 +02002409static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2410{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002411 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002412 struct hci_conn *conn;
2413
2414 BT_DBG("%s status %d", hdev->name, ev->status);
2415
2416 hci_dev_lock(hdev);
2417
2418 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419 if (conn && !ev->status) {
2420 struct inquiry_entry *ie;
2421
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002422 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2423 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424 ie->data.clock_offset = ev->clock_offset;
2425 ie->timestamp = jiffies;
2426 }
2427 }
2428
2429 hci_dev_unlock(hdev);
2430}
2431
Marcel Holtmanna8746412008-07-14 20:13:46 +02002432static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2433{
2434 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2435 struct hci_conn *conn;
2436
2437 BT_DBG("%s status %d", hdev->name, ev->status);
2438
2439 hci_dev_lock(hdev);
2440
2441 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2442 if (conn && !ev->status)
2443 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2444
2445 hci_dev_unlock(hdev);
2446}
2447
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002448static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2449{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002450 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002451 struct inquiry_entry *ie;
2452
2453 BT_DBG("%s", hdev->name);
2454
2455 hci_dev_lock(hdev);
2456
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002457 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2458 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002459 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2460 ie->timestamp = jiffies;
2461 }
2462
2463 hci_dev_unlock(hdev);
2464}
2465
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002466static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2467{
2468 struct inquiry_data data;
2469 int num_rsp = *((__u8 *) skb->data);
2470
2471 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2472
2473 if (!num_rsp)
2474 return;
2475
2476 hci_dev_lock(hdev);
2477
2478 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002479 struct inquiry_info_with_rssi_and_pscan_mode *info;
2480 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002481
Johan Hedberge17acd42011-03-30 23:57:16 +03002482 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002483 bacpy(&data.bdaddr, &info->bdaddr);
2484 data.pscan_rep_mode = info->pscan_rep_mode;
2485 data.pscan_period_mode = info->pscan_period_mode;
2486 data.pscan_mode = info->pscan_mode;
2487 memcpy(data.dev_class, info->dev_class, 3);
2488 data.clock_offset = info->clock_offset;
2489 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002490 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002491 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002492 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002493 info->dev_class, info->rssi,
2494 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002495 }
2496 } else {
2497 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2498
Johan Hedberge17acd42011-03-30 23:57:16 +03002499 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002500 bacpy(&data.bdaddr, &info->bdaddr);
2501 data.pscan_rep_mode = info->pscan_rep_mode;
2502 data.pscan_period_mode = info->pscan_period_mode;
2503 data.pscan_mode = 0x00;
2504 memcpy(data.dev_class, info->dev_class, 3);
2505 data.clock_offset = info->clock_offset;
2506 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002507 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002508 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002509 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002510 info->dev_class, info->rssi,
2511 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002512 }
2513 }
2514
2515 hci_dev_unlock(hdev);
2516}
2517
2518static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2519{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002520 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2521 struct hci_conn *conn;
2522
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002523 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002524
Marcel Holtmann41a96212008-07-14 20:13:48 +02002525 hci_dev_lock(hdev);
2526
2527 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002528 if (!conn)
2529 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002530
Johan Hedbergccd556f2010-11-10 17:11:51 +02002531 if (!ev->status && ev->page == 0x01) {
2532 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002533
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002534 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2535 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002536 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002537
Johan Hedbergccd556f2010-11-10 17:11:51 +02002538 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002539 }
2540
Johan Hedbergccd556f2010-11-10 17:11:51 +02002541 if (conn->state != BT_CONFIG)
2542 goto unlock;
2543
Johan Hedberg127178d2010-11-18 22:22:29 +02002544 if (!ev->status) {
2545 struct hci_cp_remote_name_req cp;
2546 memset(&cp, 0, sizeof(cp));
2547 bacpy(&cp.bdaddr, &conn->dst);
2548 cp.pscan_rep_mode = 0x02;
2549 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2550 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002551
Johan Hedberg127178d2010-11-18 22:22:29 +02002552 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002553 conn->state = BT_CONNECTED;
2554 hci_proto_connect_cfm(conn, ev->status);
2555 hci_conn_put(conn);
2556 }
2557
2558unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002559 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002560}
2561
2562static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2563{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002564 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2565 struct hci_conn *conn;
2566
2567 BT_DBG("%s status %d", hdev->name, ev->status);
2568
2569 hci_dev_lock(hdev);
2570
2571 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002572 if (!conn) {
2573 if (ev->link_type == ESCO_LINK)
2574 goto unlock;
2575
2576 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2577 if (!conn)
2578 goto unlock;
2579
2580 conn->type = SCO_LINK;
2581 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002582
Marcel Holtmann732547f2009-04-19 19:14:14 +02002583 switch (ev->status) {
2584 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002585 conn->handle = __le16_to_cpu(ev->handle);
2586 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002587
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002588 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002589 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002590 break;
2591
Stephen Coe705e5712010-02-16 11:29:44 -05002592 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002593 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002594 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002595 case 0x1f: /* Unspecified error */
2596 if (conn->out && conn->attempt < 2) {
2597 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2598 (hdev->esco_type & EDR_ESCO_MASK);
2599 hci_setup_sync(conn, conn->link->handle);
2600 goto unlock;
2601 }
2602 /* fall through */
2603
2604 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002605 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002606 break;
2607 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002608
2609 hci_proto_connect_cfm(conn, ev->status);
2610 if (ev->status)
2611 hci_conn_del(conn);
2612
2613unlock:
2614 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002615}
2616
2617static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2618{
2619 BT_DBG("%s", hdev->name);
2620}
2621
Marcel Holtmann04837f62006-07-03 10:02:33 +02002622static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2623{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002624 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002625
2626 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002627}
2628
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002629static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2630{
2631 struct inquiry_data data;
2632 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2633 int num_rsp = *((__u8 *) skb->data);
2634
2635 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2636
2637 if (!num_rsp)
2638 return;
2639
2640 hci_dev_lock(hdev);
2641
Johan Hedberge17acd42011-03-30 23:57:16 +03002642 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002643 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002644 data.pscan_rep_mode = info->pscan_rep_mode;
2645 data.pscan_period_mode = info->pscan_period_mode;
2646 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002647 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002648 data.clock_offset = info->clock_offset;
2649 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002650 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002651 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002652 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg4c659c32011-11-07 23:13:39 +02002653 info->dev_class, info->rssi, info->data);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002654 }
2655
2656 hci_dev_unlock(hdev);
2657}
2658
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002659static inline u8 hci_get_auth_req(struct hci_conn *conn)
2660{
2661 /* If remote requests dedicated bonding follow that lead */
2662 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2663 /* If both remote and local IO capabilities allow MITM
2664 * protection then require it, otherwise don't */
2665 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2666 return 0x02;
2667 else
2668 return 0x03;
2669 }
2670
2671 /* If remote requests no-bonding follow that lead */
2672 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002673 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002674
2675 return conn->auth_type;
2676}
2677
Marcel Holtmann04936842008-07-14 20:13:48 +02002678static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2679{
2680 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2681 struct hci_conn *conn;
2682
2683 BT_DBG("%s", hdev->name);
2684
2685 hci_dev_lock(hdev);
2686
2687 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002688 if (!conn)
2689 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002690
Johan Hedberg03b555e2011-01-04 15:40:05 +02002691 hci_conn_hold(conn);
2692
2693 if (!test_bit(HCI_MGMT, &hdev->flags))
2694 goto unlock;
2695
2696 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
2697 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002698 struct hci_cp_io_capability_reply cp;
2699
2700 bacpy(&cp.bdaddr, &ev->bdaddr);
2701 cp.capability = conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07002702 conn->auth_type = hci_get_auth_req(conn);
2703 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002704
Szymon Jancce85ee12011-03-22 13:12:23 +01002705 if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
2706 hci_find_remote_oob_data(hdev, &conn->dst))
2707 cp.oob_data = 0x01;
2708 else
2709 cp.oob_data = 0x00;
2710
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002711 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2712 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002713 } else {
2714 struct hci_cp_io_capability_neg_reply cp;
2715
2716 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002717 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02002718
2719 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2720 sizeof(cp), &cp);
2721 }
2722
2723unlock:
2724 hci_dev_unlock(hdev);
2725}
2726
2727static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2728{
2729 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2730 struct hci_conn *conn;
2731
2732 BT_DBG("%s", hdev->name);
2733
2734 hci_dev_lock(hdev);
2735
2736 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2737 if (!conn)
2738 goto unlock;
2739
Johan Hedberg03b555e2011-01-04 15:40:05 +02002740 conn->remote_cap = ev->capability;
2741 conn->remote_oob = ev->oob_data;
2742 conn->remote_auth = ev->authentication;
2743
2744unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002745 hci_dev_unlock(hdev);
2746}
2747
Johan Hedberga5c29682011-02-19 12:05:57 -03002748static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2749 struct sk_buff *skb)
2750{
2751 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002752 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07002753 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03002754
2755 BT_DBG("%s", hdev->name);
2756
2757 hci_dev_lock(hdev);
2758
Johan Hedberg7a828902011-04-28 11:28:53 -07002759 if (!test_bit(HCI_MGMT, &hdev->flags))
2760 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03002761
Johan Hedberg7a828902011-04-28 11:28:53 -07002762 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2763 if (!conn)
2764 goto unlock;
2765
2766 loc_mitm = (conn->auth_type & 0x01);
2767 rem_mitm = (conn->remote_auth & 0x01);
2768
2769 /* If we require MITM but the remote device can't provide that
2770 * (it has NoInputNoOutput) then reject the confirmation
2771 * request. The only exception is when we're dedicated bonding
2772 * initiators (connect_cfm_cb set) since then we always have the MITM
2773 * bit set. */
2774 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
2775 BT_DBG("Rejecting request: remote device can't provide MITM");
2776 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
2777 sizeof(ev->bdaddr), &ev->bdaddr);
2778 goto unlock;
2779 }
2780
2781 /* If no side requires MITM protection; auto-accept */
2782 if ((!loc_mitm || conn->remote_cap == 0x03) &&
2783 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002784
2785 /* If we're not the initiators request authorization to
2786 * proceed from user space (mgmt_user_confirm with
2787 * confirm_hint set to 1). */
2788 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
2789 BT_DBG("Confirming auto-accept as acceptor");
2790 confirm_hint = 1;
2791 goto confirm;
2792 }
2793
Johan Hedberg9f616562011-04-28 11:28:54 -07002794 BT_DBG("Auto-accept of user confirmation with %ums delay",
2795 hdev->auto_accept_delay);
2796
2797 if (hdev->auto_accept_delay > 0) {
2798 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
2799 mod_timer(&conn->auto_accept_timer, jiffies + delay);
2800 goto unlock;
2801 }
2802
Johan Hedberg7a828902011-04-28 11:28:53 -07002803 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
2804 sizeof(ev->bdaddr), &ev->bdaddr);
2805 goto unlock;
2806 }
2807
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002808confirm:
Johan Hedberg744cf192011-11-08 20:40:14 +02002809 mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002810 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07002811
2812unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03002813 hci_dev_unlock(hdev);
2814}
2815
Brian Gix1143d452011-11-23 08:28:34 -08002816static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
2817 struct sk_buff *skb)
2818{
2819 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
2820
2821 BT_DBG("%s", hdev->name);
2822
2823 hci_dev_lock(hdev);
2824
2825 if (test_bit(HCI_MGMT, &hdev->flags))
2826 mgmt_user_passkey_request(hdev, &ev->bdaddr);
2827
2828 hci_dev_unlock(hdev);
2829}
2830
Marcel Holtmann04936842008-07-14 20:13:48 +02002831static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2832{
2833 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
2834 struct hci_conn *conn;
2835
2836 BT_DBG("%s", hdev->name);
2837
2838 hci_dev_lock(hdev);
2839
2840 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03002841 if (!conn)
2842 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002843
Johan Hedberg2a611692011-02-19 12:06:00 -03002844 /* To avoid duplicate auth_failed events to user space we check
2845 * the HCI_CONN_AUTH_PEND flag which will be set if we
2846 * initiated the authentication. A traditional auth_complete
2847 * event gets always produced as initiator and is also mapped to
2848 * the mgmt_auth_failed event */
2849 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
Johan Hedberg744cf192011-11-08 20:40:14 +02002850 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03002851
2852 hci_conn_put(conn);
2853
2854unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002855 hci_dev_unlock(hdev);
2856}
2857
Marcel Holtmann41a96212008-07-14 20:13:48 +02002858static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2859{
2860 struct hci_ev_remote_host_features *ev = (void *) skb->data;
2861 struct inquiry_entry *ie;
2862
2863 BT_DBG("%s", hdev->name);
2864
2865 hci_dev_lock(hdev);
2866
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002867 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2868 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02002869 ie->data.ssp_mode = (ev->features[0] & 0x01);
2870
2871 hci_dev_unlock(hdev);
2872}
2873
Szymon Janc2763eda2011-03-22 13:12:22 +01002874static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
2875 struct sk_buff *skb)
2876{
2877 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
2878 struct oob_data *data;
2879
2880 BT_DBG("%s", hdev->name);
2881
2882 hci_dev_lock(hdev);
2883
Szymon Jance1ba1f12011-04-06 13:01:59 +02002884 if (!test_bit(HCI_MGMT, &hdev->flags))
2885 goto unlock;
2886
Szymon Janc2763eda2011-03-22 13:12:22 +01002887 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
2888 if (data) {
2889 struct hci_cp_remote_oob_data_reply cp;
2890
2891 bacpy(&cp.bdaddr, &ev->bdaddr);
2892 memcpy(cp.hash, data->hash, sizeof(cp.hash));
2893 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
2894
2895 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
2896 &cp);
2897 } else {
2898 struct hci_cp_remote_oob_data_neg_reply cp;
2899
2900 bacpy(&cp.bdaddr, &ev->bdaddr);
2901 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
2902 &cp);
2903 }
2904
Szymon Jance1ba1f12011-04-06 13:01:59 +02002905unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01002906 hci_dev_unlock(hdev);
2907}
2908
Ville Tervofcd89c02011-02-10 22:38:47 -03002909static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2910{
2911 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2912 struct hci_conn *conn;
2913
2914 BT_DBG("%s status %d", hdev->name, ev->status);
2915
2916 hci_dev_lock(hdev);
2917
2918 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03002919 if (!conn) {
2920 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
2921 if (!conn) {
2922 BT_ERR("No memory for new connection");
2923 hci_dev_unlock(hdev);
2924 return;
2925 }
Andre Guedes29b79882011-05-31 14:20:54 -03002926
2927 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03002928 }
Ville Tervofcd89c02011-02-10 22:38:47 -03002929
2930 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02002931 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
2932 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03002933 hci_proto_connect_cfm(conn, ev->status);
2934 conn->state = BT_CLOSED;
2935 hci_conn_del(conn);
2936 goto unlock;
2937 }
2938
Johan Hedberg48264f02011-11-09 13:58:58 +02002939 mgmt_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03002940
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03002941 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03002942 conn->handle = __le16_to_cpu(ev->handle);
2943 conn->state = BT_CONNECTED;
2944
2945 hci_conn_hold_device(conn);
2946 hci_conn_add_sysfs(conn);
2947
2948 hci_proto_connect_cfm(conn, ev->status);
2949
2950unlock:
2951 hci_dev_unlock(hdev);
2952}
2953
Andre Guedes9aa04c92011-05-26 16:23:51 -03002954static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
2955 struct sk_buff *skb)
2956{
Andre Guedese95beb42011-09-26 20:48:35 -03002957 u8 num_reports = skb->data[0];
2958 void *ptr = &skb->data[1];
Andre Guedes9aa04c92011-05-26 16:23:51 -03002959
2960 hci_dev_lock(hdev);
2961
Andre Guedese95beb42011-09-26 20:48:35 -03002962 while (num_reports--) {
2963 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03002964
Andre Guedes9aa04c92011-05-26 16:23:51 -03002965 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03002966
2967 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03002968 }
2969
2970 hci_dev_unlock(hdev);
2971}
2972
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002973static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
2974 struct sk_buff *skb)
2975{
2976 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
2977 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002978 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002979 struct hci_conn *conn;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002980 struct link_key *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002981
2982 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
2983
2984 hci_dev_lock(hdev);
2985
2986 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002987 if (conn == NULL)
2988 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002989
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002990 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
2991 if (ltk == NULL)
2992 goto not_found;
2993
2994 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002995 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes726b4ff2011-07-08 18:31:45 -03002996 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002997
2998 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
2999
3000 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003001
3002 return;
3003
3004not_found:
3005 neg.handle = ev->handle;
3006 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3007 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003008}
3009
Ville Tervofcd89c02011-02-10 22:38:47 -03003010static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3011{
3012 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3013
3014 skb_pull(skb, sizeof(*le_ev));
3015
3016 switch (le_ev->subevent) {
3017 case HCI_EV_LE_CONN_COMPLETE:
3018 hci_le_conn_complete_evt(hdev, skb);
3019 break;
3020
Andre Guedes9aa04c92011-05-26 16:23:51 -03003021 case HCI_EV_LE_ADVERTISING_REPORT:
3022 hci_le_adv_report_evt(hdev, skb);
3023 break;
3024
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003025 case HCI_EV_LE_LTK_REQ:
3026 hci_le_ltk_request_evt(hdev, skb);
3027 break;
3028
Ville Tervofcd89c02011-02-10 22:38:47 -03003029 default:
3030 break;
3031 }
3032}
3033
Linus Torvalds1da177e2005-04-16 15:20:36 -07003034void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3035{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003036 struct hci_event_hdr *hdr = (void *) skb->data;
3037 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003038
3039 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3040
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003041 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003042 case HCI_EV_INQUIRY_COMPLETE:
3043 hci_inquiry_complete_evt(hdev, skb);
3044 break;
3045
3046 case HCI_EV_INQUIRY_RESULT:
3047 hci_inquiry_result_evt(hdev, skb);
3048 break;
3049
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003050 case HCI_EV_CONN_COMPLETE:
3051 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003052 break;
3053
Linus Torvalds1da177e2005-04-16 15:20:36 -07003054 case HCI_EV_CONN_REQUEST:
3055 hci_conn_request_evt(hdev, skb);
3056 break;
3057
Linus Torvalds1da177e2005-04-16 15:20:36 -07003058 case HCI_EV_DISCONN_COMPLETE:
3059 hci_disconn_complete_evt(hdev, skb);
3060 break;
3061
Linus Torvalds1da177e2005-04-16 15:20:36 -07003062 case HCI_EV_AUTH_COMPLETE:
3063 hci_auth_complete_evt(hdev, skb);
3064 break;
3065
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003066 case HCI_EV_REMOTE_NAME:
3067 hci_remote_name_evt(hdev, skb);
3068 break;
3069
Linus Torvalds1da177e2005-04-16 15:20:36 -07003070 case HCI_EV_ENCRYPT_CHANGE:
3071 hci_encrypt_change_evt(hdev, skb);
3072 break;
3073
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003074 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3075 hci_change_link_key_complete_evt(hdev, skb);
3076 break;
3077
3078 case HCI_EV_REMOTE_FEATURES:
3079 hci_remote_features_evt(hdev, skb);
3080 break;
3081
3082 case HCI_EV_REMOTE_VERSION:
3083 hci_remote_version_evt(hdev, skb);
3084 break;
3085
3086 case HCI_EV_QOS_SETUP_COMPLETE:
3087 hci_qos_setup_complete_evt(hdev, skb);
3088 break;
3089
3090 case HCI_EV_CMD_COMPLETE:
3091 hci_cmd_complete_evt(hdev, skb);
3092 break;
3093
3094 case HCI_EV_CMD_STATUS:
3095 hci_cmd_status_evt(hdev, skb);
3096 break;
3097
3098 case HCI_EV_ROLE_CHANGE:
3099 hci_role_change_evt(hdev, skb);
3100 break;
3101
3102 case HCI_EV_NUM_COMP_PKTS:
3103 hci_num_comp_pkts_evt(hdev, skb);
3104 break;
3105
3106 case HCI_EV_MODE_CHANGE:
3107 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003108 break;
3109
3110 case HCI_EV_PIN_CODE_REQ:
3111 hci_pin_code_request_evt(hdev, skb);
3112 break;
3113
3114 case HCI_EV_LINK_KEY_REQ:
3115 hci_link_key_request_evt(hdev, skb);
3116 break;
3117
3118 case HCI_EV_LINK_KEY_NOTIFY:
3119 hci_link_key_notify_evt(hdev, skb);
3120 break;
3121
3122 case HCI_EV_CLOCK_OFFSET:
3123 hci_clock_offset_evt(hdev, skb);
3124 break;
3125
Marcel Holtmanna8746412008-07-14 20:13:46 +02003126 case HCI_EV_PKT_TYPE_CHANGE:
3127 hci_pkt_type_change_evt(hdev, skb);
3128 break;
3129
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003130 case HCI_EV_PSCAN_REP_MODE:
3131 hci_pscan_rep_mode_evt(hdev, skb);
3132 break;
3133
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003134 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3135 hci_inquiry_result_with_rssi_evt(hdev, skb);
3136 break;
3137
3138 case HCI_EV_REMOTE_EXT_FEATURES:
3139 hci_remote_ext_features_evt(hdev, skb);
3140 break;
3141
3142 case HCI_EV_SYNC_CONN_COMPLETE:
3143 hci_sync_conn_complete_evt(hdev, skb);
3144 break;
3145
3146 case HCI_EV_SYNC_CONN_CHANGED:
3147 hci_sync_conn_changed_evt(hdev, skb);
3148 break;
3149
Marcel Holtmann04837f62006-07-03 10:02:33 +02003150 case HCI_EV_SNIFF_SUBRATE:
3151 hci_sniff_subrate_evt(hdev, skb);
3152 break;
3153
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003154 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3155 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003156 break;
3157
Marcel Holtmann04936842008-07-14 20:13:48 +02003158 case HCI_EV_IO_CAPA_REQUEST:
3159 hci_io_capa_request_evt(hdev, skb);
3160 break;
3161
Johan Hedberg03b555e2011-01-04 15:40:05 +02003162 case HCI_EV_IO_CAPA_REPLY:
3163 hci_io_capa_reply_evt(hdev, skb);
3164 break;
3165
Johan Hedberga5c29682011-02-19 12:05:57 -03003166 case HCI_EV_USER_CONFIRM_REQUEST:
3167 hci_user_confirm_request_evt(hdev, skb);
3168 break;
3169
Brian Gix1143d452011-11-23 08:28:34 -08003170 case HCI_EV_USER_PASSKEY_REQUEST:
3171 hci_user_passkey_request_evt(hdev, skb);
3172 break;
3173
Marcel Holtmann04936842008-07-14 20:13:48 +02003174 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3175 hci_simple_pair_complete_evt(hdev, skb);
3176 break;
3177
Marcel Holtmann41a96212008-07-14 20:13:48 +02003178 case HCI_EV_REMOTE_HOST_FEATURES:
3179 hci_remote_host_features_evt(hdev, skb);
3180 break;
3181
Ville Tervofcd89c02011-02-10 22:38:47 -03003182 case HCI_EV_LE_META:
3183 hci_le_meta_evt(hdev, skb);
3184 break;
3185
Szymon Janc2763eda2011-03-22 13:12:22 +01003186 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3187 hci_remote_oob_data_request_evt(hdev, skb);
3188 break;
3189
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003190 default:
3191 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003192 break;
3193 }
3194
3195 kfree_skb(skb);
3196 hdev->stat.evt_rx++;
3197}
3198
3199/* Generate internal stack event */
3200void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3201{
3202 struct hci_event_hdr *hdr;
3203 struct hci_ev_stack_internal *ev;
3204 struct sk_buff *skb;
3205
3206 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3207 if (!skb)
3208 return;
3209
3210 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3211 hdr->evt = HCI_EV_STACK_INTERNAL;
3212 hdr->plen = sizeof(*ev) + dlen;
3213
3214 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3215 ev->type = type;
3216 memcpy(ev->data, data, dlen);
3217
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003218 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003219 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003220
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003221 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003222 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003223 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003224 kfree_skb(skb);
3225}
Andre Guedese6100a22011-06-30 19:20:54 -03003226
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003227module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003228MODULE_PARM_DESC(enable_le, "Enable LE support");