blob: b37531094c4999a6b9224056e4d5f283a9bdcece [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <net/sock.h>
39
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020040#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <asm/unaligned.h>
42
43#include <net/bluetooth/bluetooth.h>
44#include <net/bluetooth/hci_core.h>
45
Linus Torvalds1da177e2005-04-16 15:20:36 -070046/* Handle HCI Event packets */
47
Marcel Holtmanna9de9242007-10-20 13:33:56 +020048static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070049{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020050 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
Andre Guedese6d465c2011-11-09 17:14:26 -030054 if (status) {
55 hci_dev_lock(hdev);
56 mgmt_stop_discovery_failed(hdev, status);
57 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020058 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030059 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
Andre Guedes89352e72011-11-04 14:16:53 -030061 clear_bit(HCI_INQUIRY, &hdev->flags);
62
Johan Hedberg56e5cb82011-11-08 20:40:16 +020063 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020064 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020065 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010066
Johan Hedberg23bb5762010-12-21 23:01:27 +020067 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010068
Marcel Holtmanna9de9242007-10-20 13:33:56 +020069 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070070}
71
Marcel Holtmanna9de9242007-10-20 13:33:56 +020072static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070073{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020074 __u8 status = *((__u8 *) skb->data);
75
76 BT_DBG("%s status 0x%x", hdev->name, status);
77
78 if (status)
79 return;
80
Marcel Holtmanna9de9242007-10-20 13:33:56 +020081 hci_conn_check_pending(hdev);
82}
83
84static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
85{
86 BT_DBG("%s", hdev->name);
87}
88
89static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
90{
91 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
Marcel Holtmanna9de9242007-10-20 13:33:56 +020094 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
Marcel Holtmanna9de9242007-10-20 13:33:56 +020096 if (rp->status)
97 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070098
Marcel Holtmanna9de9242007-10-20 13:33:56 +020099 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200101 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
102 if (conn) {
103 if (rp->role)
104 conn->link_mode &= ~HCI_LM_MASTER;
105 else
106 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200108
109 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110}
111
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200112static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
113{
114 struct hci_rp_read_link_policy *rp = (void *) skb->data;
115 struct hci_conn *conn;
116
117 BT_DBG("%s status 0x%x", hdev->name, rp->status);
118
119 if (rp->status)
120 return;
121
122 hci_dev_lock(hdev);
123
124 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
125 if (conn)
126 conn->link_policy = __le16_to_cpu(rp->policy);
127
128 hci_dev_unlock(hdev);
129}
130
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200131static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200133 struct hci_rp_write_link_policy *rp = (void *) skb->data;
134 struct hci_conn *conn;
135 void *sent;
136
137 BT_DBG("%s status 0x%x", hdev->name, rp->status);
138
139 if (rp->status)
140 return;
141
142 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
143 if (!sent)
144 return;
145
146 hci_dev_lock(hdev);
147
148 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200149 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700150 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200151
152 hci_dev_unlock(hdev);
153}
154
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200155static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
156{
157 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
158
159 BT_DBG("%s status 0x%x", hdev->name, rp->status);
160
161 if (rp->status)
162 return;
163
164 hdev->link_policy = __le16_to_cpu(rp->policy);
165}
166
167static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
168{
169 __u8 status = *((__u8 *) skb->data);
170 void *sent;
171
172 BT_DBG("%s status 0x%x", hdev->name, status);
173
174 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
175 if (!sent)
176 return;
177
178 if (!status)
179 hdev->link_policy = get_unaligned_le16(sent);
180
Johan Hedberg23bb5762010-12-21 23:01:27 +0200181 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200182}
183
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200184static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
185{
186 __u8 status = *((__u8 *) skb->data);
187
188 BT_DBG("%s status 0x%x", hdev->name, status);
189
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300190 clear_bit(HCI_RESET, &hdev->flags);
191
Johan Hedberg23bb5762010-12-21 23:01:27 +0200192 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300193
Johan Hedberga297e972012-02-21 17:55:47 +0200194 /* Reset all non-persistent flags */
Johan Hedberg9f8ce962012-03-02 03:06:04 +0200195 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN) | BIT(HCI_PENDING_CLASS));
Andre Guedes69775ff2012-02-23 16:50:05 +0200196
197 hdev->discovery.state = DISCOVERY_STOPPED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200198}
199
200static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
201{
202 __u8 status = *((__u8 *) skb->data);
203 void *sent;
204
205 BT_DBG("%s status 0x%x", hdev->name, status);
206
207 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
208 if (!sent)
209 return;
210
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200211 hci_dev_lock(hdev);
212
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200213 if (test_bit(HCI_MGMT, &hdev->dev_flags))
214 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200215 else if (!status)
216 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 hci_dev_unlock(hdev);
Johan Hedberg3159d382012-02-24 13:47:56 +0200219
220 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200221}
222
223static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
224{
225 struct hci_rp_read_local_name *rp = (void *) skb->data;
226
227 BT_DBG("%s status 0x%x", hdev->name, rp->status);
228
229 if (rp->status)
230 return;
231
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200232 if (test_bit(HCI_SETUP, &hdev->dev_flags))
233 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200234}
235
236static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
237{
238 __u8 status = *((__u8 *) skb->data);
239 void *sent;
240
241 BT_DBG("%s status 0x%x", hdev->name, status);
242
243 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
244 if (!sent)
245 return;
246
247 if (!status) {
248 __u8 param = *((__u8 *) sent);
249
250 if (param == AUTH_ENABLED)
251 set_bit(HCI_AUTH, &hdev->flags);
252 else
253 clear_bit(HCI_AUTH, &hdev->flags);
254 }
255
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200256 if (test_bit(HCI_MGMT, &hdev->dev_flags))
257 mgmt_auth_enable_complete(hdev, status);
258
Johan Hedberg23bb5762010-12-21 23:01:27 +0200259 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200260}
261
262static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
263{
264 __u8 status = *((__u8 *) skb->data);
265 void *sent;
266
267 BT_DBG("%s status 0x%x", hdev->name, status);
268
269 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
270 if (!sent)
271 return;
272
273 if (!status) {
274 __u8 param = *((__u8 *) sent);
275
276 if (param)
277 set_bit(HCI_ENCRYPT, &hdev->flags);
278 else
279 clear_bit(HCI_ENCRYPT, &hdev->flags);
280 }
281
Johan Hedberg23bb5762010-12-21 23:01:27 +0200282 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200283}
284
285static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
286{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200287 __u8 param, status = *((__u8 *) skb->data);
288 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200289 void *sent;
290
291 BT_DBG("%s status 0x%x", hdev->name, status);
292
293 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
294 if (!sent)
295 return;
296
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200297 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200298
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200299 hci_dev_lock(hdev);
300
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200301 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200302 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200303 hdev->discov_timeout = 0;
304 goto done;
305 }
306
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200307 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
308 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200309
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200310 if (param & SCAN_INQUIRY) {
311 set_bit(HCI_ISCAN, &hdev->flags);
312 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200313 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200314 if (hdev->discov_timeout > 0) {
315 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
316 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
317 to);
318 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200319 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200320 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200321
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200322 if (param & SCAN_PAGE) {
323 set_bit(HCI_PSCAN, &hdev->flags);
324 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200325 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200326 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200327 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200328
329done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200330 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200331 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200332}
333
334static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
335{
336 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
337
338 BT_DBG("%s status 0x%x", hdev->name, rp->status);
339
340 if (rp->status)
341 return;
342
343 memcpy(hdev->dev_class, rp->dev_class, 3);
344
345 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
346 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
347}
348
349static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
350{
351 __u8 status = *((__u8 *) skb->data);
352 void *sent;
353
354 BT_DBG("%s status 0x%x", hdev->name, status);
355
356 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
357 if (!sent)
358 return;
359
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100360 hci_dev_lock(hdev);
361
362 if (status == 0)
363 memcpy(hdev->dev_class, sent, 3);
364
365 if (test_bit(HCI_MGMT, &hdev->dev_flags))
366 mgmt_set_class_of_dev_complete(hdev, sent, status);
367
368 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200369}
370
371static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
372{
373 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375
376 BT_DBG("%s status 0x%x", hdev->name, rp->status);
377
378 if (rp->status)
379 return;
380
381 setting = __le16_to_cpu(rp->voice_setting);
382
Marcel Holtmannf383f272008-07-14 20:13:47 +0200383 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384 return;
385
386 hdev->voice_setting = setting;
387
388 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
389
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200390 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200391 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392}
393
394static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
395{
396 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200397 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 void *sent;
399
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200400 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401
Marcel Holtmannf383f272008-07-14 20:13:47 +0200402 if (status)
403 return;
404
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200405 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
406 if (!sent)
407 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Marcel Holtmannf383f272008-07-14 20:13:47 +0200409 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
Marcel Holtmannf383f272008-07-14 20:13:47 +0200411 if (hdev->voice_setting == setting)
412 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413
Marcel Holtmannf383f272008-07-14 20:13:47 +0200414 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415
Marcel Holtmannf383f272008-07-14 20:13:47 +0200416 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
417
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200418 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200419 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420}
421
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200422static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200424 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200426 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427
Johan Hedberg23bb5762010-12-21 23:01:27 +0200428 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429}
430
Marcel Holtmann333140b2008-07-14 20:13:48 +0200431static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
432{
433 __u8 status = *((__u8 *) skb->data);
434 void *sent;
435
436 BT_DBG("%s status 0x%x", hdev->name, status);
437
Marcel Holtmann333140b2008-07-14 20:13:48 +0200438 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
439 if (!sent)
440 return;
441
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200442 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200443 mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status);
444 else if (!status) {
445 if (*((u8 *) sent))
446 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
447 else
448 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
449 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200450}
451
Johan Hedbergd5859e22011-01-25 01:19:58 +0200452static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
453{
454 if (hdev->features[6] & LMP_EXT_INQ)
455 return 2;
456
457 if (hdev->features[3] & LMP_RSSI_INQ)
458 return 1;
459
460 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
461 hdev->lmp_subver == 0x0757)
462 return 1;
463
464 if (hdev->manufacturer == 15) {
465 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
466 return 1;
467 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
468 return 1;
469 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
470 return 1;
471 }
472
473 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
474 hdev->lmp_subver == 0x1805)
475 return 1;
476
477 return 0;
478}
479
480static void hci_setup_inquiry_mode(struct hci_dev *hdev)
481{
482 u8 mode;
483
484 mode = hci_get_inquiry_mode(hdev);
485
486 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
487}
488
489static void hci_setup_event_mask(struct hci_dev *hdev)
490{
491 /* The second byte is 0xff instead of 0x9f (two reserved bits
492 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
493 * command otherwise */
494 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
495
Ville Tervo6de6c182011-05-27 11:16:21 +0300496 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
497 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200498 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300499 return;
500
501 events[4] |= 0x01; /* Flow Specification Complete */
502 events[4] |= 0x02; /* Inquiry Result with RSSI */
503 events[4] |= 0x04; /* Read Remote Extended Features Complete */
504 events[5] |= 0x08; /* Synchronous Connection Complete */
505 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200506
507 if (hdev->features[3] & LMP_RSSI_INQ)
508 events[4] |= 0x04; /* Inquiry Result with RSSI */
509
510 if (hdev->features[5] & LMP_SNIFF_SUBR)
511 events[5] |= 0x20; /* Sniff Subrating */
512
513 if (hdev->features[5] & LMP_PAUSE_ENC)
514 events[5] |= 0x80; /* Encryption Key Refresh Complete */
515
516 if (hdev->features[6] & LMP_EXT_INQ)
517 events[5] |= 0x40; /* Extended Inquiry Result */
518
519 if (hdev->features[6] & LMP_NO_FLUSH)
520 events[7] |= 0x01; /* Enhanced Flush Complete */
521
522 if (hdev->features[7] & LMP_LSTO)
523 events[6] |= 0x80; /* Link Supervision Timeout Changed */
524
525 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
526 events[6] |= 0x01; /* IO Capability Request */
527 events[6] |= 0x02; /* IO Capability Response */
528 events[6] |= 0x04; /* User Confirmation Request */
529 events[6] |= 0x08; /* User Passkey Request */
530 events[6] |= 0x10; /* Remote OOB Data Request */
531 events[6] |= 0x20; /* Simple Pairing Complete */
532 events[7] |= 0x04; /* User Passkey Notification */
533 events[7] |= 0x08; /* Keypress Notification */
534 events[7] |= 0x10; /* Remote Host Supported
535 * Features Notification */
536 }
537
538 if (hdev->features[4] & LMP_LE)
539 events[7] |= 0x20; /* LE Meta-Event */
540
541 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
542}
543
544static void hci_setup(struct hci_dev *hdev)
545{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200546 if (hdev->dev_type != HCI_BREDR)
547 return;
548
Johan Hedbergd5859e22011-01-25 01:19:58 +0200549 hci_setup_event_mask(hdev);
550
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200551 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200552 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
553
Johan Hedberg54d04db2012-02-22 15:47:48 +0200554 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
555 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
556 u8 mode = 0x01;
557 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300558 sizeof(mode), &mode);
Johan Hedberg54d04db2012-02-22 15:47:48 +0200559 } else {
560 struct hci_cp_write_eir cp;
561
562 memset(hdev->eir, 0, sizeof(hdev->eir));
563 memset(&cp, 0, sizeof(cp));
564
565 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
566 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200567 }
568
569 if (hdev->features[3] & LMP_RSSI_INQ)
570 hci_setup_inquiry_mode(hdev);
571
572 if (hdev->features[7] & LMP_INQ_TX_PWR)
573 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300574
575 if (hdev->features[7] & LMP_EXTFEATURES) {
576 struct hci_cp_read_local_ext_features cp;
577
578 cp.page = 0x01;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300579 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp),
580 &cp);
Andre Guedes971e3a42011-06-30 19:20:52 -0300581 }
Andre Guedese6100a22011-06-30 19:20:54 -0300582
Johan Hedberg47990ea2012-02-22 11:58:37 +0200583 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
584 u8 enable = 1;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300585 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
586 &enable);
Johan Hedberg47990ea2012-02-22 11:58:37 +0200587 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200588}
589
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200590static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
591{
592 struct hci_rp_read_local_version *rp = (void *) skb->data;
593
594 BT_DBG("%s status 0x%x", hdev->name, rp->status);
595
596 if (rp->status)
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200597 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200598
599 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200600 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200601 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200602 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200603 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200604
605 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
606 hdev->manufacturer,
607 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200608
609 if (test_bit(HCI_INIT, &hdev->flags))
610 hci_setup(hdev);
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200611
612done:
613 hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200614}
615
616static void hci_setup_link_policy(struct hci_dev *hdev)
617{
618 u16 link_policy = 0;
619
620 if (hdev->features[0] & LMP_RSWITCH)
621 link_policy |= HCI_LP_RSWITCH;
622 if (hdev->features[0] & LMP_HOLD)
623 link_policy |= HCI_LP_HOLD;
624 if (hdev->features[0] & LMP_SNIFF)
625 link_policy |= HCI_LP_SNIFF;
626 if (hdev->features[1] & LMP_PARK)
627 link_policy |= HCI_LP_PARK;
628
629 link_policy = cpu_to_le16(link_policy);
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300630 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(link_policy),
631 &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200632}
633
634static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
635{
636 struct hci_rp_read_local_commands *rp = (void *) skb->data;
637
638 BT_DBG("%s status 0x%x", hdev->name, rp->status);
639
640 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200641 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200642
643 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200644
645 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
646 hci_setup_link_policy(hdev);
647
648done:
649 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200650}
651
652static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
653{
654 struct hci_rp_read_local_features *rp = (void *) skb->data;
655
656 BT_DBG("%s status 0x%x", hdev->name, rp->status);
657
658 if (rp->status)
659 return;
660
661 memcpy(hdev->features, rp->features, 8);
662
663 /* Adjust default settings according to features
664 * supported by device. */
665
666 if (hdev->features[0] & LMP_3SLOT)
667 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
668
669 if (hdev->features[0] & LMP_5SLOT)
670 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
671
672 if (hdev->features[1] & LMP_HV2) {
673 hdev->pkt_type |= (HCI_HV2);
674 hdev->esco_type |= (ESCO_HV2);
675 }
676
677 if (hdev->features[1] & LMP_HV3) {
678 hdev->pkt_type |= (HCI_HV3);
679 hdev->esco_type |= (ESCO_HV3);
680 }
681
682 if (hdev->features[3] & LMP_ESCO)
683 hdev->esco_type |= (ESCO_EV3);
684
685 if (hdev->features[4] & LMP_EV4)
686 hdev->esco_type |= (ESCO_EV4);
687
688 if (hdev->features[4] & LMP_EV5)
689 hdev->esco_type |= (ESCO_EV5);
690
Marcel Holtmannefc76882009-02-06 09:13:37 +0100691 if (hdev->features[5] & LMP_EDR_ESCO_2M)
692 hdev->esco_type |= (ESCO_2EV3);
693
694 if (hdev->features[5] & LMP_EDR_ESCO_3M)
695 hdev->esco_type |= (ESCO_3EV3);
696
697 if (hdev->features[5] & LMP_EDR_3S_ESCO)
698 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
699
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200700 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
701 hdev->features[0], hdev->features[1],
702 hdev->features[2], hdev->features[3],
703 hdev->features[4], hdev->features[5],
704 hdev->features[6], hdev->features[7]);
705}
706
Johan Hedberg8f984df2012-02-28 01:07:22 +0200707static void hci_set_le_support(struct hci_dev *hdev)
708{
709 struct hci_cp_write_le_host_supported cp;
710
711 memset(&cp, 0, sizeof(cp));
712
713 if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
714 cp.le = 1;
715 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
716 }
717
718 if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300719 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
720 &cp);
Johan Hedberg8f984df2012-02-28 01:07:22 +0200721}
722
Andre Guedes971e3a42011-06-30 19:20:52 -0300723static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
724 struct sk_buff *skb)
725{
726 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
727
728 BT_DBG("%s status 0x%x", hdev->name, rp->status);
729
730 if (rp->status)
Johan Hedberg8f984df2012-02-28 01:07:22 +0200731 goto done;
Andre Guedes971e3a42011-06-30 19:20:52 -0300732
Andre Guedesb5b32b62011-12-30 10:34:04 -0300733 switch (rp->page) {
734 case 0:
735 memcpy(hdev->features, rp->features, 8);
736 break;
737 case 1:
738 memcpy(hdev->host_features, rp->features, 8);
739 break;
740 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300741
Johan Hedberg8f984df2012-02-28 01:07:22 +0200742 if (test_bit(HCI_INIT, &hdev->flags) && hdev->features[4] & LMP_LE)
743 hci_set_le_support(hdev);
744
745done:
Andre Guedes971e3a42011-06-30 19:20:52 -0300746 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
747}
748
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200749static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
750 struct sk_buff *skb)
751{
752 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
753
754 BT_DBG("%s status 0x%x", hdev->name, rp->status);
755
756 if (rp->status)
757 return;
758
759 hdev->flow_ctl_mode = rp->mode;
760
761 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
762}
763
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200764static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
765{
766 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
767
768 BT_DBG("%s status 0x%x", hdev->name, rp->status);
769
770 if (rp->status)
771 return;
772
773 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
774 hdev->sco_mtu = rp->sco_mtu;
775 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
776 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
777
778 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
779 hdev->sco_mtu = 64;
780 hdev->sco_pkts = 8;
781 }
782
783 hdev->acl_cnt = hdev->acl_pkts;
784 hdev->sco_cnt = hdev->sco_pkts;
785
786 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
787 hdev->acl_mtu, hdev->acl_pkts,
788 hdev->sco_mtu, hdev->sco_pkts);
789}
790
791static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
792{
793 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
794
795 BT_DBG("%s status 0x%x", hdev->name, rp->status);
796
797 if (!rp->status)
798 bacpy(&hdev->bdaddr, &rp->bdaddr);
799
Johan Hedberg23bb5762010-12-21 23:01:27 +0200800 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
801}
802
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200803static void hci_cc_read_data_block_size(struct hci_dev *hdev,
804 struct sk_buff *skb)
805{
806 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
807
808 BT_DBG("%s status 0x%x", hdev->name, rp->status);
809
810 if (rp->status)
811 return;
812
813 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
814 hdev->block_len = __le16_to_cpu(rp->block_len);
815 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
816
817 hdev->block_cnt = hdev->num_blocks;
818
819 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
820 hdev->block_cnt, hdev->block_len);
821
822 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
823}
824
Johan Hedberg23bb5762010-12-21 23:01:27 +0200825static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
826{
827 __u8 status = *((__u8 *) skb->data);
828
829 BT_DBG("%s status 0x%x", hdev->name, status);
830
831 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200832}
833
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300834static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
835 struct sk_buff *skb)
836{
837 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
838
839 BT_DBG("%s status 0x%x", hdev->name, rp->status);
840
841 if (rp->status)
842 return;
843
844 hdev->amp_status = rp->amp_status;
845 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
846 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
847 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
848 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
849 hdev->amp_type = rp->amp_type;
850 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
851 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
852 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
853 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
854
855 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
856}
857
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200858static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
859 struct sk_buff *skb)
860{
861 __u8 status = *((__u8 *) skb->data);
862
863 BT_DBG("%s status 0x%x", hdev->name, status);
864
865 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
866}
867
Johan Hedbergd5859e22011-01-25 01:19:58 +0200868static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
869{
870 __u8 status = *((__u8 *) skb->data);
871
872 BT_DBG("%s status 0x%x", hdev->name, status);
873
874 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
875}
876
877static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
878 struct sk_buff *skb)
879{
880 __u8 status = *((__u8 *) skb->data);
881
882 BT_DBG("%s status 0x%x", hdev->name, status);
883
884 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
885}
886
887static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
888 struct sk_buff *skb)
889{
890 __u8 status = *((__u8 *) skb->data);
891
892 BT_DBG("%s status 0x%x", hdev->name, status);
893
894 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
895}
896
897static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
898{
899 __u8 status = *((__u8 *) skb->data);
900
901 BT_DBG("%s status 0x%x", hdev->name, status);
902
903 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
904}
905
Johan Hedberg980e1a52011-01-22 06:10:07 +0200906static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
907{
908 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
909 struct hci_cp_pin_code_reply *cp;
910 struct hci_conn *conn;
911
912 BT_DBG("%s status 0x%x", hdev->name, rp->status);
913
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200914 hci_dev_lock(hdev);
915
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200916 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200917 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200918
919 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200920 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200921
922 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
923 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200924 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200925
926 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
927 if (conn)
928 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200929
930unlock:
931 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200932}
933
934static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
935{
936 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
937
938 BT_DBG("%s status 0x%x", hdev->name, rp->status);
939
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200940 hci_dev_lock(hdev);
941
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200942 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200943 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200944 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200945
946 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200947}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200948
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300949static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
950 struct sk_buff *skb)
951{
952 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
953
954 BT_DBG("%s status 0x%x", hdev->name, rp->status);
955
956 if (rp->status)
957 return;
958
959 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
960 hdev->le_pkts = rp->le_max_pkt;
961
962 hdev->le_cnt = hdev->le_pkts;
963
964 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
965
966 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
967}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200968
Johan Hedberga5c29682011-02-19 12:05:57 -0300969static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
970{
971 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
972
973 BT_DBG("%s status 0x%x", hdev->name, rp->status);
974
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200975 hci_dev_lock(hdev);
976
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200977 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300978 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
979 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200980
981 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300982}
983
984static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
985 struct sk_buff *skb)
986{
987 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
988
989 BT_DBG("%s status 0x%x", hdev->name, rp->status);
990
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200991 hci_dev_lock(hdev);
992
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200993 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200994 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300995 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200996
997 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300998}
999
Brian Gix1143d452011-11-23 08:28:34 -08001000static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
1001{
1002 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1003
1004 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1005
1006 hci_dev_lock(hdev);
1007
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001008 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001009 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001010 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001011
1012 hci_dev_unlock(hdev);
1013}
1014
1015static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1016 struct sk_buff *skb)
1017{
1018 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1019
1020 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1021
1022 hci_dev_lock(hdev);
1023
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001024 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001025 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001026 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001027
1028 hci_dev_unlock(hdev);
1029}
1030
Szymon Jancc35938b2011-03-22 13:12:21 +01001031static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1032 struct sk_buff *skb)
1033{
1034 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1035
1036 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1037
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001038 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001039 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001040 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001041 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001042}
1043
Andre Guedes07f7fa52011-12-02 21:13:31 +09001044static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1045{
1046 __u8 status = *((__u8 *) skb->data);
1047
1048 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001049
1050 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001051
1052 if (status) {
1053 hci_dev_lock(hdev);
1054 mgmt_start_discovery_failed(hdev, status);
1055 hci_dev_unlock(hdev);
1056 return;
1057 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001058}
1059
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001060static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1061 struct sk_buff *skb)
1062{
1063 struct hci_cp_le_set_scan_enable *cp;
1064 __u8 status = *((__u8 *) skb->data);
1065
1066 BT_DBG("%s status 0x%x", hdev->name, status);
1067
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001068 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1069 if (!cp)
1070 return;
1071
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001072 switch (cp->enable) {
1073 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001074 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1075
Andre Guedes3fd24152012-02-03 17:48:01 -03001076 if (status) {
1077 hci_dev_lock(hdev);
1078 mgmt_start_discovery_failed(hdev, status);
1079 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001080 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001081 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001082
Andre Guedesd23264a2011-11-25 20:53:38 -03001083 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1084
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001085 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001086
1087 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001088 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001089 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001090 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001091 break;
1092
1093 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001094 if (status)
1095 return;
1096
Andre Guedesd23264a2011-11-25 20:53:38 -03001097 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1098
Andre Guedesd0843292012-01-02 19:18:11 -03001099 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001100
1101 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1102 mgmt_interleaved_discovery(hdev);
1103 } else {
1104 hci_dev_lock(hdev);
1105 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1106 hci_dev_unlock(hdev);
1107 }
1108
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001109 break;
1110
1111 default:
1112 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1113 break;
Andre Guedes35815082011-05-26 16:23:53 -03001114 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001115}
1116
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001117static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1118{
1119 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1120
1121 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1122
1123 if (rp->status)
1124 return;
1125
1126 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1127}
1128
1129static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1130{
1131 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1132
1133 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1134
1135 if (rp->status)
1136 return;
1137
1138 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1139}
1140
Andre Guedesf9b49302011-06-30 19:20:53 -03001141static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1142 struct sk_buff *skb)
1143{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001144 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001145 __u8 status = *((__u8 *) skb->data);
1146
1147 BT_DBG("%s status 0x%x", hdev->name, status);
1148
Johan Hedberg06199cf2012-02-22 16:37:11 +02001149 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001150 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001151 return;
1152
Johan Hedberg8f984df2012-02-28 01:07:22 +02001153 if (!status) {
1154 if (sent->le)
1155 hdev->host_features[0] |= LMP_HOST_LE;
1156 else
1157 hdev->host_features[0] &= ~LMP_HOST_LE;
1158 }
1159
1160 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
1161 !test_bit(HCI_INIT, &hdev->flags))
1162 mgmt_le_enable_complete(hdev, sent->le, status);
1163
1164 hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001165}
1166
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001167static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1168{
1169 BT_DBG("%s status 0x%x", hdev->name, status);
1170
1171 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001172 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001173 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001174 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001175 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001176 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001177 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001178 return;
1179 }
1180
Andre Guedes89352e72011-11-04 14:16:53 -03001181 set_bit(HCI_INQUIRY, &hdev->flags);
1182
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001183 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001184 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001185 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001186}
1187
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1189{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001190 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001193 BT_DBG("%s status 0x%x", hdev->name, status);
1194
1195 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196 if (!cp)
1197 return;
1198
1199 hci_dev_lock(hdev);
1200
1201 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1202
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001203 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204
1205 if (status) {
1206 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001207 if (status != 0x0c || conn->attempt > 2) {
1208 conn->state = BT_CLOSED;
1209 hci_proto_connect_cfm(conn, status);
1210 hci_conn_del(conn);
1211 } else
1212 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 }
1214 } else {
1215 if (!conn) {
1216 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1217 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001218 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 conn->link_mode |= HCI_LM_MASTER;
1220 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001221 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 }
1223 }
1224
1225 hci_dev_unlock(hdev);
1226}
1227
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001228static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001230 struct hci_cp_add_sco *cp;
1231 struct hci_conn *acl, *sco;
1232 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001234 BT_DBG("%s status 0x%x", hdev->name, status);
1235
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001236 if (!status)
1237 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001239 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1240 if (!cp)
1241 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001243 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001245 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001246
1247 hci_dev_lock(hdev);
1248
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001249 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001250 if (acl) {
1251 sco = acl->link;
1252 if (sco) {
1253 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001254
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001255 hci_proto_connect_cfm(sco, status);
1256 hci_conn_del(sco);
1257 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001258 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001259
1260 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261}
1262
Marcel Holtmannf8558552008-07-14 20:13:49 +02001263static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1264{
1265 struct hci_cp_auth_requested *cp;
1266 struct hci_conn *conn;
1267
1268 BT_DBG("%s status 0x%x", hdev->name, status);
1269
1270 if (!status)
1271 return;
1272
1273 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1274 if (!cp)
1275 return;
1276
1277 hci_dev_lock(hdev);
1278
1279 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1280 if (conn) {
1281 if (conn->state == BT_CONFIG) {
1282 hci_proto_connect_cfm(conn, status);
1283 hci_conn_put(conn);
1284 }
1285 }
1286
1287 hci_dev_unlock(hdev);
1288}
1289
1290static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1291{
1292 struct hci_cp_set_conn_encrypt *cp;
1293 struct hci_conn *conn;
1294
1295 BT_DBG("%s status 0x%x", hdev->name, status);
1296
1297 if (!status)
1298 return;
1299
1300 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1301 if (!cp)
1302 return;
1303
1304 hci_dev_lock(hdev);
1305
1306 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1307 if (conn) {
1308 if (conn->state == BT_CONFIG) {
1309 hci_proto_connect_cfm(conn, status);
1310 hci_conn_put(conn);
1311 }
1312 }
1313
1314 hci_dev_unlock(hdev);
1315}
1316
Johan Hedberg127178d2010-11-18 22:22:29 +02001317static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001318 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001319{
Johan Hedberg392599b2010-11-18 22:22:28 +02001320 if (conn->state != BT_CONFIG || !conn->out)
1321 return 0;
1322
Johan Hedberg765c2a92011-01-19 12:06:52 +05301323 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001324 return 0;
1325
1326 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001327 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001328 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001329 conn->pending_sec_level != BT_SECURITY_HIGH &&
1330 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001331 return 0;
1332
Johan Hedberg392599b2010-11-18 22:22:28 +02001333 return 1;
1334}
1335
Gustavo F. Padovan00abfe42012-03-01 00:37:10 -03001336static inline int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001337 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001338{
1339 struct hci_cp_remote_name_req cp;
1340
1341 memset(&cp, 0, sizeof(cp));
1342
1343 bacpy(&cp.bdaddr, &e->data.bdaddr);
1344 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1345 cp.pscan_mode = e->data.pscan_mode;
1346 cp.clock_offset = e->data.clock_offset;
1347
1348 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1349}
1350
Johan Hedbergb644ba32012-01-17 21:48:47 +02001351static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001352{
1353 struct discovery_state *discov = &hdev->discovery;
1354 struct inquiry_entry *e;
1355
Johan Hedbergb644ba32012-01-17 21:48:47 +02001356 if (list_empty(&discov->resolve))
1357 return false;
1358
1359 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1360 if (hci_resolve_name(hdev, e) == 0) {
1361 e->name_state = NAME_PENDING;
1362 return true;
1363 }
1364
1365 return false;
1366}
1367
1368static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001369 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001370{
1371 struct discovery_state *discov = &hdev->discovery;
1372 struct inquiry_entry *e;
1373
1374 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001375 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1376 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001377
1378 if (discov->state == DISCOVERY_STOPPED)
1379 return;
1380
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001381 if (discov->state == DISCOVERY_STOPPING)
1382 goto discov_complete;
1383
1384 if (discov->state != DISCOVERY_RESOLVING)
1385 return;
1386
1387 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1388 if (e) {
1389 e->name_state = NAME_KNOWN;
1390 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001391 if (name)
1392 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001393 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001394 }
1395
Johan Hedbergb644ba32012-01-17 21:48:47 +02001396 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001397 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001398
1399discov_complete:
1400 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1401}
1402
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001403static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1404{
Johan Hedberg127178d2010-11-18 22:22:29 +02001405 struct hci_cp_remote_name_req *cp;
1406 struct hci_conn *conn;
1407
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001408 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001409
1410 /* If successful wait for the name req complete event before
1411 * checking for the need to do authentication */
1412 if (!status)
1413 return;
1414
1415 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1416 if (!cp)
1417 return;
1418
1419 hci_dev_lock(hdev);
1420
1421 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001422
1423 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1424 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1425
Johan Hedberg79c6c702011-04-28 11:28:55 -07001426 if (!conn)
1427 goto unlock;
1428
1429 if (!hci_outgoing_auth_needed(hdev, conn))
1430 goto unlock;
1431
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001432 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001433 struct hci_cp_auth_requested cp;
1434 cp.handle = __cpu_to_le16(conn->handle);
1435 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1436 }
1437
Johan Hedberg79c6c702011-04-28 11:28:55 -07001438unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001439 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001440}
1441
Marcel Holtmann769be972008-07-14 20:13:49 +02001442static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1443{
1444 struct hci_cp_read_remote_features *cp;
1445 struct hci_conn *conn;
1446
1447 BT_DBG("%s status 0x%x", hdev->name, status);
1448
1449 if (!status)
1450 return;
1451
1452 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1453 if (!cp)
1454 return;
1455
1456 hci_dev_lock(hdev);
1457
1458 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1459 if (conn) {
1460 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001461 hci_proto_connect_cfm(conn, status);
1462 hci_conn_put(conn);
1463 }
1464 }
1465
1466 hci_dev_unlock(hdev);
1467}
1468
1469static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1470{
1471 struct hci_cp_read_remote_ext_features *cp;
1472 struct hci_conn *conn;
1473
1474 BT_DBG("%s status 0x%x", hdev->name, status);
1475
1476 if (!status)
1477 return;
1478
1479 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1480 if (!cp)
1481 return;
1482
1483 hci_dev_lock(hdev);
1484
1485 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1486 if (conn) {
1487 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001488 hci_proto_connect_cfm(conn, status);
1489 hci_conn_put(conn);
1490 }
1491 }
1492
1493 hci_dev_unlock(hdev);
1494}
1495
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001496static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1497{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001498 struct hci_cp_setup_sync_conn *cp;
1499 struct hci_conn *acl, *sco;
1500 __u16 handle;
1501
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001502 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001503
1504 if (!status)
1505 return;
1506
1507 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1508 if (!cp)
1509 return;
1510
1511 handle = __le16_to_cpu(cp->handle);
1512
1513 BT_DBG("%s handle %d", hdev->name, handle);
1514
1515 hci_dev_lock(hdev);
1516
1517 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001518 if (acl) {
1519 sco = acl->link;
1520 if (sco) {
1521 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001522
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001523 hci_proto_connect_cfm(sco, status);
1524 hci_conn_del(sco);
1525 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001526 }
1527
1528 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001529}
1530
1531static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1532{
1533 struct hci_cp_sniff_mode *cp;
1534 struct hci_conn *conn;
1535
1536 BT_DBG("%s status 0x%x", hdev->name, status);
1537
1538 if (!status)
1539 return;
1540
1541 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1542 if (!cp)
1543 return;
1544
1545 hci_dev_lock(hdev);
1546
1547 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001548 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001549 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001550
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001551 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001552 hci_sco_setup(conn, status);
1553 }
1554
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001555 hci_dev_unlock(hdev);
1556}
1557
1558static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1559{
1560 struct hci_cp_exit_sniff_mode *cp;
1561 struct hci_conn *conn;
1562
1563 BT_DBG("%s status 0x%x", hdev->name, status);
1564
1565 if (!status)
1566 return;
1567
1568 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1569 if (!cp)
1570 return;
1571
1572 hci_dev_lock(hdev);
1573
1574 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001575 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001576 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001577
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001578 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001579 hci_sco_setup(conn, status);
1580 }
1581
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001582 hci_dev_unlock(hdev);
1583}
1584
Johan Hedberg88c3df12012-02-09 14:27:38 +02001585static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1586{
1587 struct hci_cp_disconnect *cp;
1588 struct hci_conn *conn;
1589
1590 if (!status)
1591 return;
1592
1593 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1594 if (!cp)
1595 return;
1596
1597 hci_dev_lock(hdev);
1598
1599 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1600 if (conn)
1601 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001602 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001603
1604 hci_dev_unlock(hdev);
1605}
1606
Ville Tervofcd89c02011-02-10 22:38:47 -03001607static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1608{
1609 struct hci_cp_le_create_conn *cp;
1610 struct hci_conn *conn;
1611
1612 BT_DBG("%s status 0x%x", hdev->name, status);
1613
1614 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1615 if (!cp)
1616 return;
1617
1618 hci_dev_lock(hdev);
1619
1620 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1621
1622 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1623 conn);
1624
1625 if (status) {
1626 if (conn && conn->state == BT_CONNECT) {
1627 conn->state = BT_CLOSED;
1628 hci_proto_connect_cfm(conn, status);
1629 hci_conn_del(conn);
1630 }
1631 } else {
1632 if (!conn) {
1633 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001634 if (conn) {
1635 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001636 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001637 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001638 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001639 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001640 }
1641 }
1642
1643 hci_dev_unlock(hdev);
1644}
1645
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001646static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1647{
1648 BT_DBG("%s status 0x%x", hdev->name, status);
1649}
1650
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001651static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1652{
1653 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001654 struct discovery_state *discov = &hdev->discovery;
1655 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001656
1657 BT_DBG("%s status %d", hdev->name, status);
1658
Johan Hedberg23bb5762010-12-21 23:01:27 +02001659 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001660
1661 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001662
1663 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1664 return;
1665
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001666 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001667 return;
1668
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001669 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001670
Andre Guedes343f9352012-02-17 20:39:37 -03001671 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001672 goto unlock;
1673
1674 if (list_empty(&discov->resolve)) {
1675 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1676 goto unlock;
1677 }
1678
1679 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1680 if (e && hci_resolve_name(hdev, e) == 0) {
1681 e->name_state = NAME_PENDING;
1682 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1683 } else {
1684 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1685 }
1686
1687unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001688 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001689}
1690
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1692{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001693 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001694 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695 int num_rsp = *((__u8 *) skb->data);
1696
1697 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1698
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001699 if (!num_rsp)
1700 return;
1701
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001703
Johan Hedberge17acd42011-03-30 23:57:16 +03001704 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001705 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001706
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 bacpy(&data.bdaddr, &info->bdaddr);
1708 data.pscan_rep_mode = info->pscan_rep_mode;
1709 data.pscan_period_mode = info->pscan_period_mode;
1710 data.pscan_mode = info->pscan_mode;
1711 memcpy(data.dev_class, info->dev_class, 3);
1712 data.clock_offset = info->clock_offset;
1713 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001714 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001715
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001716 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001717 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001718 info->dev_class, 0, !name_known, ssp, NULL,
1719 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001721
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 hci_dev_unlock(hdev);
1723}
1724
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001725static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001727 struct hci_ev_conn_complete *ev = (void *) skb->data;
1728 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001730 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001731
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001733
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001734 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001735 if (!conn) {
1736 if (ev->link_type != SCO_LINK)
1737 goto unlock;
1738
1739 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1740 if (!conn)
1741 goto unlock;
1742
1743 conn->type = SCO_LINK;
1744 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001745
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001746 if (!ev->status) {
1747 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001748
1749 if (conn->type == ACL_LINK) {
1750 conn->state = BT_CONFIG;
1751 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001752 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001753 } else
1754 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001755
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001756 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001757 hci_conn_add_sysfs(conn);
1758
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001759 if (test_bit(HCI_AUTH, &hdev->flags))
1760 conn->link_mode |= HCI_LM_AUTH;
1761
1762 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1763 conn->link_mode |= HCI_LM_ENCRYPT;
1764
1765 /* Get remote features */
1766 if (conn->type == ACL_LINK) {
1767 struct hci_cp_read_remote_features cp;
1768 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001769 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001770 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001771 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001772
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001773 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001774 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001775 struct hci_cp_change_conn_ptype cp;
1776 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001777 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001778 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1779 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001780 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001781 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001782 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001783 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001784 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001785 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001786 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001787
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001788 if (conn->type == ACL_LINK)
1789 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001790
Marcel Holtmann769be972008-07-14 20:13:49 +02001791 if (ev->status) {
1792 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001793 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001794 } else if (ev->link_type != ACL_LINK)
1795 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001796
1797unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001799
1800 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801}
1802
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1804{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001805 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 int mask = hdev->link_mode;
1807
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001808 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1809 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810
1811 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1812
Szymon Janc138d22e2011-02-17 16:44:23 +01001813 if ((mask & HCI_LM_ACCEPT) &&
1814 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001816 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818
1819 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001820
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001821 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1822 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001823 memcpy(ie->data.dev_class, ev->dev_class, 3);
1824
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1826 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001827 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1828 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001829 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 hci_dev_unlock(hdev);
1831 return;
1832 }
1833 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001834
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 memcpy(conn->dev_class, ev->dev_class, 3);
1836 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001837
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 hci_dev_unlock(hdev);
1839
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001840 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1841 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001843 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001845 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1846 cp.role = 0x00; /* Become master */
1847 else
1848 cp.role = 0x01; /* Remain slave */
1849
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001850 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1851 &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001852 } else {
1853 struct hci_cp_accept_sync_conn_req cp;
1854
1855 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001856 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001857
1858 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1859 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1860 cp.max_latency = cpu_to_le16(0xffff);
1861 cp.content_format = cpu_to_le16(hdev->voice_setting);
1862 cp.retrans_effort = 0xff;
1863
1864 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001865 sizeof(cp), &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001866 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 } else {
1868 /* Connection rejected */
1869 struct hci_cp_reject_conn_req cp;
1870
1871 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001872 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001873 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874 }
1875}
1876
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1878{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001879 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001880 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881
1882 BT_DBG("%s status %d", hdev->name, ev->status);
1883
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 hci_dev_lock(hdev);
1885
Marcel Holtmann04837f62006-07-03 10:02:33 +02001886 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001887 if (!conn)
1888 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001889
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001890 if (ev->status == 0)
1891 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892
Johan Hedbergb644ba32012-01-17 21:48:47 +02001893 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1894 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001895 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001896 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1897 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001898 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001899 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001900 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001901 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001902
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001903 if (ev->status == 0) {
1904 hci_proto_disconn_cfm(conn, ev->reason);
1905 hci_conn_del(conn);
1906 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001907
1908unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 hci_dev_unlock(hdev);
1910}
1911
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001912static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1913{
1914 struct hci_ev_auth_complete *ev = (void *) skb->data;
1915 struct hci_conn *conn;
1916
1917 BT_DBG("%s status %d", hdev->name, ev->status);
1918
1919 hci_dev_lock(hdev);
1920
1921 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001922 if (!conn)
1923 goto unlock;
1924
1925 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001926 if (!hci_conn_ssp_enabled(conn) &&
1927 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001928 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001929 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001930 conn->link_mode |= HCI_LM_AUTH;
1931 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001932 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001933 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001934 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001935 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001936 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001937
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001938 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1939 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001940
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001941 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001942 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001943 struct hci_cp_set_conn_encrypt cp;
1944 cp.handle = ev->handle;
1945 cp.encrypt = 0x01;
1946 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1947 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001948 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001949 conn->state = BT_CONNECTED;
1950 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001951 hci_conn_put(conn);
1952 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001953 } else {
1954 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001955
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001956 hci_conn_hold(conn);
1957 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1958 hci_conn_put(conn);
1959 }
1960
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001961 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001962 if (!ev->status) {
1963 struct hci_cp_set_conn_encrypt cp;
1964 cp.handle = ev->handle;
1965 cp.encrypt = 0x01;
1966 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1967 &cp);
1968 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001969 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001970 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001971 }
1972 }
1973
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001974unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001975 hci_dev_unlock(hdev);
1976}
1977
1978static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1979{
Johan Hedberg127178d2010-11-18 22:22:29 +02001980 struct hci_ev_remote_name *ev = (void *) skb->data;
1981 struct hci_conn *conn;
1982
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001983 BT_DBG("%s", hdev->name);
1984
1985 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001986
1987 hci_dev_lock(hdev);
1988
1989 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001990
1991 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1992 goto check_auth;
1993
1994 if (ev->status == 0)
1995 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001996 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001997 else
1998 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1999
2000check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002001 if (!conn)
2002 goto unlock;
2003
2004 if (!hci_outgoing_auth_needed(hdev, conn))
2005 goto unlock;
2006
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002007 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002008 struct hci_cp_auth_requested cp;
2009 cp.handle = __cpu_to_le16(conn->handle);
2010 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2011 }
2012
Johan Hedberg79c6c702011-04-28 11:28:55 -07002013unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002014 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002015}
2016
2017static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2018{
2019 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2020 struct hci_conn *conn;
2021
2022 BT_DBG("%s status %d", hdev->name, ev->status);
2023
2024 hci_dev_lock(hdev);
2025
2026 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2027 if (conn) {
2028 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002029 if (ev->encrypt) {
2030 /* Encryption implies authentication */
2031 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002032 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002033 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002034 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002035 conn->link_mode &= ~HCI_LM_ENCRYPT;
2036 }
2037
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002038 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002039
Marcel Holtmannf8558552008-07-14 20:13:49 +02002040 if (conn->state == BT_CONFIG) {
2041 if (!ev->status)
2042 conn->state = BT_CONNECTED;
2043
2044 hci_proto_connect_cfm(conn, ev->status);
2045 hci_conn_put(conn);
2046 } else
2047 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002048 }
2049
2050 hci_dev_unlock(hdev);
2051}
2052
2053static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2054{
2055 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2056 struct hci_conn *conn;
2057
2058 BT_DBG("%s status %d", hdev->name, ev->status);
2059
2060 hci_dev_lock(hdev);
2061
2062 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2063 if (conn) {
2064 if (!ev->status)
2065 conn->link_mode |= HCI_LM_SECURE;
2066
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002067 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002068
2069 hci_key_change_cfm(conn, ev->status);
2070 }
2071
2072 hci_dev_unlock(hdev);
2073}
2074
2075static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2076{
2077 struct hci_ev_remote_features *ev = (void *) skb->data;
2078 struct hci_conn *conn;
2079
2080 BT_DBG("%s status %d", hdev->name, ev->status);
2081
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002082 hci_dev_lock(hdev);
2083
2084 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002085 if (!conn)
2086 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002087
Johan Hedbergccd556f2010-11-10 17:11:51 +02002088 if (!ev->status)
2089 memcpy(conn->features, ev->features, 8);
2090
2091 if (conn->state != BT_CONFIG)
2092 goto unlock;
2093
2094 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2095 struct hci_cp_read_remote_ext_features cp;
2096 cp.handle = ev->handle;
2097 cp.page = 0x01;
2098 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002099 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002100 goto unlock;
2101 }
2102
Johan Hedberg127178d2010-11-18 22:22:29 +02002103 if (!ev->status) {
2104 struct hci_cp_remote_name_req cp;
2105 memset(&cp, 0, sizeof(cp));
2106 bacpy(&cp.bdaddr, &conn->dst);
2107 cp.pscan_rep_mode = 0x02;
2108 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002109 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2110 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002111 conn->dst_type, 0, NULL, 0,
2112 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002113
Johan Hedberg127178d2010-11-18 22:22:29 +02002114 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002115 conn->state = BT_CONNECTED;
2116 hci_proto_connect_cfm(conn, ev->status);
2117 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002118 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002119
Johan Hedbergccd556f2010-11-10 17:11:51 +02002120unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002121 hci_dev_unlock(hdev);
2122}
2123
2124static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2125{
2126 BT_DBG("%s", hdev->name);
2127}
2128
2129static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2130{
2131 BT_DBG("%s", hdev->name);
2132}
2133
2134static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2135{
2136 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2137 __u16 opcode;
2138
2139 skb_pull(skb, sizeof(*ev));
2140
2141 opcode = __le16_to_cpu(ev->opcode);
2142
2143 switch (opcode) {
2144 case HCI_OP_INQUIRY_CANCEL:
2145 hci_cc_inquiry_cancel(hdev, skb);
2146 break;
2147
2148 case HCI_OP_EXIT_PERIODIC_INQ:
2149 hci_cc_exit_periodic_inq(hdev, skb);
2150 break;
2151
2152 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2153 hci_cc_remote_name_req_cancel(hdev, skb);
2154 break;
2155
2156 case HCI_OP_ROLE_DISCOVERY:
2157 hci_cc_role_discovery(hdev, skb);
2158 break;
2159
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002160 case HCI_OP_READ_LINK_POLICY:
2161 hci_cc_read_link_policy(hdev, skb);
2162 break;
2163
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002164 case HCI_OP_WRITE_LINK_POLICY:
2165 hci_cc_write_link_policy(hdev, skb);
2166 break;
2167
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002168 case HCI_OP_READ_DEF_LINK_POLICY:
2169 hci_cc_read_def_link_policy(hdev, skb);
2170 break;
2171
2172 case HCI_OP_WRITE_DEF_LINK_POLICY:
2173 hci_cc_write_def_link_policy(hdev, skb);
2174 break;
2175
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002176 case HCI_OP_RESET:
2177 hci_cc_reset(hdev, skb);
2178 break;
2179
2180 case HCI_OP_WRITE_LOCAL_NAME:
2181 hci_cc_write_local_name(hdev, skb);
2182 break;
2183
2184 case HCI_OP_READ_LOCAL_NAME:
2185 hci_cc_read_local_name(hdev, skb);
2186 break;
2187
2188 case HCI_OP_WRITE_AUTH_ENABLE:
2189 hci_cc_write_auth_enable(hdev, skb);
2190 break;
2191
2192 case HCI_OP_WRITE_ENCRYPT_MODE:
2193 hci_cc_write_encrypt_mode(hdev, skb);
2194 break;
2195
2196 case HCI_OP_WRITE_SCAN_ENABLE:
2197 hci_cc_write_scan_enable(hdev, skb);
2198 break;
2199
2200 case HCI_OP_READ_CLASS_OF_DEV:
2201 hci_cc_read_class_of_dev(hdev, skb);
2202 break;
2203
2204 case HCI_OP_WRITE_CLASS_OF_DEV:
2205 hci_cc_write_class_of_dev(hdev, skb);
2206 break;
2207
2208 case HCI_OP_READ_VOICE_SETTING:
2209 hci_cc_read_voice_setting(hdev, skb);
2210 break;
2211
2212 case HCI_OP_WRITE_VOICE_SETTING:
2213 hci_cc_write_voice_setting(hdev, skb);
2214 break;
2215
2216 case HCI_OP_HOST_BUFFER_SIZE:
2217 hci_cc_host_buffer_size(hdev, skb);
2218 break;
2219
Marcel Holtmann333140b2008-07-14 20:13:48 +02002220 case HCI_OP_WRITE_SSP_MODE:
2221 hci_cc_write_ssp_mode(hdev, skb);
2222 break;
2223
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002224 case HCI_OP_READ_LOCAL_VERSION:
2225 hci_cc_read_local_version(hdev, skb);
2226 break;
2227
2228 case HCI_OP_READ_LOCAL_COMMANDS:
2229 hci_cc_read_local_commands(hdev, skb);
2230 break;
2231
2232 case HCI_OP_READ_LOCAL_FEATURES:
2233 hci_cc_read_local_features(hdev, skb);
2234 break;
2235
Andre Guedes971e3a42011-06-30 19:20:52 -03002236 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2237 hci_cc_read_local_ext_features(hdev, skb);
2238 break;
2239
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002240 case HCI_OP_READ_BUFFER_SIZE:
2241 hci_cc_read_buffer_size(hdev, skb);
2242 break;
2243
2244 case HCI_OP_READ_BD_ADDR:
2245 hci_cc_read_bd_addr(hdev, skb);
2246 break;
2247
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002248 case HCI_OP_READ_DATA_BLOCK_SIZE:
2249 hci_cc_read_data_block_size(hdev, skb);
2250 break;
2251
Johan Hedberg23bb5762010-12-21 23:01:27 +02002252 case HCI_OP_WRITE_CA_TIMEOUT:
2253 hci_cc_write_ca_timeout(hdev, skb);
2254 break;
2255
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002256 case HCI_OP_READ_FLOW_CONTROL_MODE:
2257 hci_cc_read_flow_control_mode(hdev, skb);
2258 break;
2259
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002260 case HCI_OP_READ_LOCAL_AMP_INFO:
2261 hci_cc_read_local_amp_info(hdev, skb);
2262 break;
2263
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002264 case HCI_OP_DELETE_STORED_LINK_KEY:
2265 hci_cc_delete_stored_link_key(hdev, skb);
2266 break;
2267
Johan Hedbergd5859e22011-01-25 01:19:58 +02002268 case HCI_OP_SET_EVENT_MASK:
2269 hci_cc_set_event_mask(hdev, skb);
2270 break;
2271
2272 case HCI_OP_WRITE_INQUIRY_MODE:
2273 hci_cc_write_inquiry_mode(hdev, skb);
2274 break;
2275
2276 case HCI_OP_READ_INQ_RSP_TX_POWER:
2277 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2278 break;
2279
2280 case HCI_OP_SET_EVENT_FLT:
2281 hci_cc_set_event_flt(hdev, skb);
2282 break;
2283
Johan Hedberg980e1a52011-01-22 06:10:07 +02002284 case HCI_OP_PIN_CODE_REPLY:
2285 hci_cc_pin_code_reply(hdev, skb);
2286 break;
2287
2288 case HCI_OP_PIN_CODE_NEG_REPLY:
2289 hci_cc_pin_code_neg_reply(hdev, skb);
2290 break;
2291
Szymon Jancc35938b2011-03-22 13:12:21 +01002292 case HCI_OP_READ_LOCAL_OOB_DATA:
2293 hci_cc_read_local_oob_data_reply(hdev, skb);
2294 break;
2295
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002296 case HCI_OP_LE_READ_BUFFER_SIZE:
2297 hci_cc_le_read_buffer_size(hdev, skb);
2298 break;
2299
Johan Hedberga5c29682011-02-19 12:05:57 -03002300 case HCI_OP_USER_CONFIRM_REPLY:
2301 hci_cc_user_confirm_reply(hdev, skb);
2302 break;
2303
2304 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2305 hci_cc_user_confirm_neg_reply(hdev, skb);
2306 break;
2307
Brian Gix1143d452011-11-23 08:28:34 -08002308 case HCI_OP_USER_PASSKEY_REPLY:
2309 hci_cc_user_passkey_reply(hdev, skb);
2310 break;
2311
2312 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2313 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002314
2315 case HCI_OP_LE_SET_SCAN_PARAM:
2316 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002317 break;
2318
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002319 case HCI_OP_LE_SET_SCAN_ENABLE:
2320 hci_cc_le_set_scan_enable(hdev, skb);
2321 break;
2322
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002323 case HCI_OP_LE_LTK_REPLY:
2324 hci_cc_le_ltk_reply(hdev, skb);
2325 break;
2326
2327 case HCI_OP_LE_LTK_NEG_REPLY:
2328 hci_cc_le_ltk_neg_reply(hdev, skb);
2329 break;
2330
Andre Guedesf9b49302011-06-30 19:20:53 -03002331 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2332 hci_cc_write_le_host_supported(hdev, skb);
2333 break;
2334
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002335 default:
2336 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2337 break;
2338 }
2339
Ville Tervo6bd32322011-02-16 16:32:41 +02002340 if (ev->opcode != HCI_OP_NOP)
2341 del_timer(&hdev->cmd_timer);
2342
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002343 if (ev->ncmd) {
2344 atomic_set(&hdev->cmd_cnt, 1);
2345 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002346 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002347 }
2348}
2349
2350static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2351{
2352 struct hci_ev_cmd_status *ev = (void *) skb->data;
2353 __u16 opcode;
2354
2355 skb_pull(skb, sizeof(*ev));
2356
2357 opcode = __le16_to_cpu(ev->opcode);
2358
2359 switch (opcode) {
2360 case HCI_OP_INQUIRY:
2361 hci_cs_inquiry(hdev, ev->status);
2362 break;
2363
2364 case HCI_OP_CREATE_CONN:
2365 hci_cs_create_conn(hdev, ev->status);
2366 break;
2367
2368 case HCI_OP_ADD_SCO:
2369 hci_cs_add_sco(hdev, ev->status);
2370 break;
2371
Marcel Holtmannf8558552008-07-14 20:13:49 +02002372 case HCI_OP_AUTH_REQUESTED:
2373 hci_cs_auth_requested(hdev, ev->status);
2374 break;
2375
2376 case HCI_OP_SET_CONN_ENCRYPT:
2377 hci_cs_set_conn_encrypt(hdev, ev->status);
2378 break;
2379
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002380 case HCI_OP_REMOTE_NAME_REQ:
2381 hci_cs_remote_name_req(hdev, ev->status);
2382 break;
2383
Marcel Holtmann769be972008-07-14 20:13:49 +02002384 case HCI_OP_READ_REMOTE_FEATURES:
2385 hci_cs_read_remote_features(hdev, ev->status);
2386 break;
2387
2388 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2389 hci_cs_read_remote_ext_features(hdev, ev->status);
2390 break;
2391
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002392 case HCI_OP_SETUP_SYNC_CONN:
2393 hci_cs_setup_sync_conn(hdev, ev->status);
2394 break;
2395
2396 case HCI_OP_SNIFF_MODE:
2397 hci_cs_sniff_mode(hdev, ev->status);
2398 break;
2399
2400 case HCI_OP_EXIT_SNIFF_MODE:
2401 hci_cs_exit_sniff_mode(hdev, ev->status);
2402 break;
2403
Johan Hedberg8962ee72011-01-20 12:40:27 +02002404 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002405 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002406 break;
2407
Ville Tervofcd89c02011-02-10 22:38:47 -03002408 case HCI_OP_LE_CREATE_CONN:
2409 hci_cs_le_create_conn(hdev, ev->status);
2410 break;
2411
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002412 case HCI_OP_LE_START_ENC:
2413 hci_cs_le_start_enc(hdev, ev->status);
2414 break;
2415
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002416 default:
2417 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2418 break;
2419 }
2420
Ville Tervo6bd32322011-02-16 16:32:41 +02002421 if (ev->opcode != HCI_OP_NOP)
2422 del_timer(&hdev->cmd_timer);
2423
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002424 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002425 atomic_set(&hdev->cmd_cnt, 1);
2426 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002427 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002428 }
2429}
2430
2431static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2432{
2433 struct hci_ev_role_change *ev = (void *) skb->data;
2434 struct hci_conn *conn;
2435
2436 BT_DBG("%s status %d", hdev->name, ev->status);
2437
2438 hci_dev_lock(hdev);
2439
2440 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2441 if (conn) {
2442 if (!ev->status) {
2443 if (ev->role)
2444 conn->link_mode &= ~HCI_LM_MASTER;
2445 else
2446 conn->link_mode |= HCI_LM_MASTER;
2447 }
2448
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002449 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002450
2451 hci_role_switch_cfm(conn, ev->status, ev->role);
2452 }
2453
2454 hci_dev_unlock(hdev);
2455}
2456
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2458{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002459 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460 int i;
2461
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002462 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2463 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2464 return;
2465 }
2466
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002467 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2468 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002469 BT_DBG("%s bad parameters", hdev->name);
2470 return;
2471 }
2472
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002473 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2474
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002475 for (i = 0; i < ev->num_hndl; i++) {
2476 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002477 struct hci_conn *conn;
2478 __u16 handle, count;
2479
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002480 handle = __le16_to_cpu(info->handle);
2481 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482
2483 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002484 if (!conn)
2485 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002487 conn->sent -= count;
2488
2489 switch (conn->type) {
2490 case ACL_LINK:
2491 hdev->acl_cnt += count;
2492 if (hdev->acl_cnt > hdev->acl_pkts)
2493 hdev->acl_cnt = hdev->acl_pkts;
2494 break;
2495
2496 case LE_LINK:
2497 if (hdev->le_pkts) {
2498 hdev->le_cnt += count;
2499 if (hdev->le_cnt > hdev->le_pkts)
2500 hdev->le_cnt = hdev->le_pkts;
2501 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002502 hdev->acl_cnt += count;
2503 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504 hdev->acl_cnt = hdev->acl_pkts;
2505 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002506 break;
2507
2508 case SCO_LINK:
2509 hdev->sco_cnt += count;
2510 if (hdev->sco_cnt > hdev->sco_pkts)
2511 hdev->sco_cnt = hdev->sco_pkts;
2512 break;
2513
2514 default:
2515 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2516 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002517 }
2518 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002519
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002520 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002521}
2522
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002523static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002524 struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002525{
2526 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2527 int i;
2528
2529 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2530 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2531 return;
2532 }
2533
2534 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2535 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2536 BT_DBG("%s bad parameters", hdev->name);
2537 return;
2538 }
2539
2540 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2541 ev->num_hndl);
2542
2543 for (i = 0; i < ev->num_hndl; i++) {
2544 struct hci_comp_blocks_info *info = &ev->handles[i];
2545 struct hci_conn *conn;
2546 __u16 handle, block_count;
2547
2548 handle = __le16_to_cpu(info->handle);
2549 block_count = __le16_to_cpu(info->blocks);
2550
2551 conn = hci_conn_hash_lookup_handle(hdev, handle);
2552 if (!conn)
2553 continue;
2554
2555 conn->sent -= block_count;
2556
2557 switch (conn->type) {
2558 case ACL_LINK:
2559 hdev->block_cnt += block_count;
2560 if (hdev->block_cnt > hdev->num_blocks)
2561 hdev->block_cnt = hdev->num_blocks;
2562 break;
2563
2564 default:
2565 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2566 break;
2567 }
2568 }
2569
2570 queue_work(hdev->workqueue, &hdev->tx_work);
2571}
2572
Marcel Holtmann04837f62006-07-03 10:02:33 +02002573static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002574{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002575 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002576 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577
2578 BT_DBG("%s status %d", hdev->name, ev->status);
2579
2580 hci_dev_lock(hdev);
2581
Marcel Holtmann04837f62006-07-03 10:02:33 +02002582 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2583 if (conn) {
2584 conn->mode = ev->mode;
2585 conn->interval = __le16_to_cpu(ev->interval);
2586
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002587 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002588 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002589 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002590 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002591 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002592 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002593
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002594 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002595 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002596 }
2597
2598 hci_dev_unlock(hdev);
2599}
2600
Linus Torvalds1da177e2005-04-16 15:20:36 -07002601static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2602{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002603 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2604 struct hci_conn *conn;
2605
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002606 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002607
2608 hci_dev_lock(hdev);
2609
2610 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002611 if (!conn)
2612 goto unlock;
2613
2614 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002615 hci_conn_hold(conn);
2616 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2617 hci_conn_put(conn);
2618 }
2619
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002620 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002621 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2622 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002623 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002624 u8 secure;
2625
2626 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2627 secure = 1;
2628 else
2629 secure = 0;
2630
Johan Hedberg744cf192011-11-08 20:40:14 +02002631 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002632 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002633
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002634unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002635 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636}
2637
Linus Torvalds1da177e2005-04-16 15:20:36 -07002638static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2639{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002640 struct hci_ev_link_key_req *ev = (void *) skb->data;
2641 struct hci_cp_link_key_reply cp;
2642 struct hci_conn *conn;
2643 struct link_key *key;
2644
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002645 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002646
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002647 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002648 return;
2649
2650 hci_dev_lock(hdev);
2651
2652 key = hci_find_link_key(hdev, &ev->bdaddr);
2653 if (!key) {
2654 BT_DBG("%s link key not found for %s", hdev->name,
2655 batostr(&ev->bdaddr));
2656 goto not_found;
2657 }
2658
2659 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2660 batostr(&ev->bdaddr));
2661
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002662 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002663 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002664 BT_DBG("%s ignoring debug key", hdev->name);
2665 goto not_found;
2666 }
2667
2668 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002669 if (conn) {
2670 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2671 conn->auth_type != 0xff &&
2672 (conn->auth_type & 0x01)) {
2673 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2674 goto not_found;
2675 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002676
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002677 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2678 conn->pending_sec_level == BT_SECURITY_HIGH) {
2679 BT_DBG("%s ignoring key unauthenticated for high \
2680 security", hdev->name);
2681 goto not_found;
2682 }
2683
2684 conn->key_type = key->type;
2685 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002686 }
2687
2688 bacpy(&cp.bdaddr, &ev->bdaddr);
2689 memcpy(cp.link_key, key->val, 16);
2690
2691 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2692
2693 hci_dev_unlock(hdev);
2694
2695 return;
2696
2697not_found:
2698 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2699 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002700}
2701
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2703{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002704 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2705 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002706 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002707
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002708 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002709
2710 hci_dev_lock(hdev);
2711
2712 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2713 if (conn) {
2714 hci_conn_hold(conn);
2715 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002716 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002717
2718 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2719 conn->key_type = ev->key_type;
2720
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002721 hci_conn_put(conn);
2722 }
2723
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002724 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002725 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002726 ev->key_type, pin_len);
2727
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002728 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002729}
2730
Marcel Holtmann04837f62006-07-03 10:02:33 +02002731static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2732{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002733 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002734 struct hci_conn *conn;
2735
2736 BT_DBG("%s status %d", hdev->name, ev->status);
2737
2738 hci_dev_lock(hdev);
2739
2740 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741 if (conn && !ev->status) {
2742 struct inquiry_entry *ie;
2743
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002744 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2745 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746 ie->data.clock_offset = ev->clock_offset;
2747 ie->timestamp = jiffies;
2748 }
2749 }
2750
2751 hci_dev_unlock(hdev);
2752}
2753
Marcel Holtmanna8746412008-07-14 20:13:46 +02002754static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2755{
2756 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2757 struct hci_conn *conn;
2758
2759 BT_DBG("%s status %d", hdev->name, ev->status);
2760
2761 hci_dev_lock(hdev);
2762
2763 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2764 if (conn && !ev->status)
2765 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2766
2767 hci_dev_unlock(hdev);
2768}
2769
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002770static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2771{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002772 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002773 struct inquiry_entry *ie;
2774
2775 BT_DBG("%s", hdev->name);
2776
2777 hci_dev_lock(hdev);
2778
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002779 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2780 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002781 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2782 ie->timestamp = jiffies;
2783 }
2784
2785 hci_dev_unlock(hdev);
2786}
2787
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002788static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2789{
2790 struct inquiry_data data;
2791 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002792 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002793
2794 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2795
2796 if (!num_rsp)
2797 return;
2798
2799 hci_dev_lock(hdev);
2800
2801 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002802 struct inquiry_info_with_rssi_and_pscan_mode *info;
2803 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002804
Johan Hedberge17acd42011-03-30 23:57:16 +03002805 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002806 bacpy(&data.bdaddr, &info->bdaddr);
2807 data.pscan_rep_mode = info->pscan_rep_mode;
2808 data.pscan_period_mode = info->pscan_period_mode;
2809 data.pscan_mode = info->pscan_mode;
2810 memcpy(data.dev_class, info->dev_class, 3);
2811 data.clock_offset = info->clock_offset;
2812 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002813 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002814
2815 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002816 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002817 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002818 info->dev_class, info->rssi,
2819 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002820 }
2821 } else {
2822 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2823
Johan Hedberge17acd42011-03-30 23:57:16 +03002824 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002825 bacpy(&data.bdaddr, &info->bdaddr);
2826 data.pscan_rep_mode = info->pscan_rep_mode;
2827 data.pscan_period_mode = info->pscan_period_mode;
2828 data.pscan_mode = 0x00;
2829 memcpy(data.dev_class, info->dev_class, 3);
2830 data.clock_offset = info->clock_offset;
2831 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002832 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002833 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002834 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002835 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002836 info->dev_class, info->rssi,
2837 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002838 }
2839 }
2840
2841 hci_dev_unlock(hdev);
2842}
2843
2844static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2845{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002846 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2847 struct hci_conn *conn;
2848
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002849 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002850
Marcel Holtmann41a96212008-07-14 20:13:48 +02002851 hci_dev_lock(hdev);
2852
2853 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002854 if (!conn)
2855 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002856
Johan Hedbergccd556f2010-11-10 17:11:51 +02002857 if (!ev->status && ev->page == 0x01) {
2858 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002859
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002860 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2861 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002862 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002863
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002864 if (ev->features[0] & LMP_HOST_SSP)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002865 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002866 }
2867
Johan Hedbergccd556f2010-11-10 17:11:51 +02002868 if (conn->state != BT_CONFIG)
2869 goto unlock;
2870
Johan Hedberg127178d2010-11-18 22:22:29 +02002871 if (!ev->status) {
2872 struct hci_cp_remote_name_req cp;
2873 memset(&cp, 0, sizeof(cp));
2874 bacpy(&cp.bdaddr, &conn->dst);
2875 cp.pscan_rep_mode = 0x02;
2876 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002877 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2878 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002879 conn->dst_type, 0, NULL, 0,
2880 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002881
Johan Hedberg127178d2010-11-18 22:22:29 +02002882 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002883 conn->state = BT_CONNECTED;
2884 hci_proto_connect_cfm(conn, ev->status);
2885 hci_conn_put(conn);
2886 }
2887
2888unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002889 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002890}
2891
2892static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2893{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002894 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2895 struct hci_conn *conn;
2896
2897 BT_DBG("%s status %d", hdev->name, ev->status);
2898
2899 hci_dev_lock(hdev);
2900
2901 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002902 if (!conn) {
2903 if (ev->link_type == ESCO_LINK)
2904 goto unlock;
2905
2906 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2907 if (!conn)
2908 goto unlock;
2909
2910 conn->type = SCO_LINK;
2911 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002912
Marcel Holtmann732547f2009-04-19 19:14:14 +02002913 switch (ev->status) {
2914 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002915 conn->handle = __le16_to_cpu(ev->handle);
2916 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002917
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002918 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002919 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002920 break;
2921
Stephen Coe705e5712010-02-16 11:29:44 -05002922 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002923 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002924 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002925 case 0x1f: /* Unspecified error */
2926 if (conn->out && conn->attempt < 2) {
2927 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2928 (hdev->esco_type & EDR_ESCO_MASK);
2929 hci_setup_sync(conn, conn->link->handle);
2930 goto unlock;
2931 }
2932 /* fall through */
2933
2934 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002935 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002936 break;
2937 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002938
2939 hci_proto_connect_cfm(conn, ev->status);
2940 if (ev->status)
2941 hci_conn_del(conn);
2942
2943unlock:
2944 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002945}
2946
2947static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2948{
2949 BT_DBG("%s", hdev->name);
2950}
2951
Marcel Holtmann04837f62006-07-03 10:02:33 +02002952static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2953{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002954 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002955
2956 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002957}
2958
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002959static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2960{
2961 struct inquiry_data data;
2962 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2963 int num_rsp = *((__u8 *) skb->data);
2964
2965 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2966
2967 if (!num_rsp)
2968 return;
2969
2970 hci_dev_lock(hdev);
2971
Johan Hedberge17acd42011-03-30 23:57:16 +03002972 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002973 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002974
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002975 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002976 data.pscan_rep_mode = info->pscan_rep_mode;
2977 data.pscan_period_mode = info->pscan_period_mode;
2978 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002979 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002980 data.clock_offset = info->clock_offset;
2981 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002982 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002983
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002984 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002985 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002986 sizeof(info->data),
2987 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002988 else
2989 name_known = true;
2990
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002991 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002992 &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002993 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002994 info->dev_class, info->rssi, !name_known,
2995 ssp, info->data, sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002996 }
2997
2998 hci_dev_unlock(hdev);
2999}
3000
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003001static inline u8 hci_get_auth_req(struct hci_conn *conn)
3002{
3003 /* If remote requests dedicated bonding follow that lead */
3004 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3005 /* If both remote and local IO capabilities allow MITM
3006 * protection then require it, otherwise don't */
3007 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3008 return 0x02;
3009 else
3010 return 0x03;
3011 }
3012
3013 /* If remote requests no-bonding follow that lead */
3014 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003015 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003016
3017 return conn->auth_type;
3018}
3019
Marcel Holtmann04936842008-07-14 20:13:48 +02003020static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3021{
3022 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3023 struct hci_conn *conn;
3024
3025 BT_DBG("%s", hdev->name);
3026
3027 hci_dev_lock(hdev);
3028
3029 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003030 if (!conn)
3031 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003032
Johan Hedberg03b555e2011-01-04 15:40:05 +02003033 hci_conn_hold(conn);
3034
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003035 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003036 goto unlock;
3037
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003038 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003039 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003040 struct hci_cp_io_capability_reply cp;
3041
3042 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303043 /* Change the IO capability from KeyboardDisplay
3044 * to DisplayYesNo as it is not supported by BT spec. */
3045 cp.capability = (conn->io_capability == 0x04) ?
3046 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003047 conn->auth_type = hci_get_auth_req(conn);
3048 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003049
Johan Hedberg58a681e2012-01-16 06:47:28 +02003050 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003051 hci_find_remote_oob_data(hdev, &conn->dst))
3052 cp.oob_data = 0x01;
3053 else
3054 cp.oob_data = 0x00;
3055
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003056 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3057 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003058 } else {
3059 struct hci_cp_io_capability_neg_reply cp;
3060
3061 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003062 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003063
3064 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3065 sizeof(cp), &cp);
3066 }
3067
3068unlock:
3069 hci_dev_unlock(hdev);
3070}
3071
3072static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3073{
3074 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3075 struct hci_conn *conn;
3076
3077 BT_DBG("%s", hdev->name);
3078
3079 hci_dev_lock(hdev);
3080
3081 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3082 if (!conn)
3083 goto unlock;
3084
Johan Hedberg03b555e2011-01-04 15:40:05 +02003085 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003086 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003087 if (ev->oob_data)
3088 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003089
3090unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003091 hci_dev_unlock(hdev);
3092}
3093
Johan Hedberga5c29682011-02-19 12:05:57 -03003094static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3095 struct sk_buff *skb)
3096{
3097 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003098 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003099 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003100
3101 BT_DBG("%s", hdev->name);
3102
3103 hci_dev_lock(hdev);
3104
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003105 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003106 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003107
Johan Hedberg7a828902011-04-28 11:28:53 -07003108 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3109 if (!conn)
3110 goto unlock;
3111
3112 loc_mitm = (conn->auth_type & 0x01);
3113 rem_mitm = (conn->remote_auth & 0x01);
3114
3115 /* If we require MITM but the remote device can't provide that
3116 * (it has NoInputNoOutput) then reject the confirmation
3117 * request. The only exception is when we're dedicated bonding
3118 * initiators (connect_cfm_cb set) since then we always have the MITM
3119 * bit set. */
3120 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3121 BT_DBG("Rejecting request: remote device can't provide MITM");
3122 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3123 sizeof(ev->bdaddr), &ev->bdaddr);
3124 goto unlock;
3125 }
3126
3127 /* If no side requires MITM protection; auto-accept */
3128 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3129 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003130
3131 /* If we're not the initiators request authorization to
3132 * proceed from user space (mgmt_user_confirm with
3133 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003134 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003135 BT_DBG("Confirming auto-accept as acceptor");
3136 confirm_hint = 1;
3137 goto confirm;
3138 }
3139
Johan Hedberg9f616562011-04-28 11:28:54 -07003140 BT_DBG("Auto-accept of user confirmation with %ums delay",
3141 hdev->auto_accept_delay);
3142
3143 if (hdev->auto_accept_delay > 0) {
3144 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3145 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3146 goto unlock;
3147 }
3148
Johan Hedberg7a828902011-04-28 11:28:53 -07003149 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3150 sizeof(ev->bdaddr), &ev->bdaddr);
3151 goto unlock;
3152 }
3153
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003154confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003155 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003156 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003157
3158unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003159 hci_dev_unlock(hdev);
3160}
3161
Brian Gix1143d452011-11-23 08:28:34 -08003162static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3163 struct sk_buff *skb)
3164{
3165 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3166
3167 BT_DBG("%s", hdev->name);
3168
3169 hci_dev_lock(hdev);
3170
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003171 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003172 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003173
3174 hci_dev_unlock(hdev);
3175}
3176
Marcel Holtmann04936842008-07-14 20:13:48 +02003177static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3178{
3179 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3180 struct hci_conn *conn;
3181
3182 BT_DBG("%s", hdev->name);
3183
3184 hci_dev_lock(hdev);
3185
3186 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003187 if (!conn)
3188 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003189
Johan Hedberg2a611692011-02-19 12:06:00 -03003190 /* To avoid duplicate auth_failed events to user space we check
3191 * the HCI_CONN_AUTH_PEND flag which will be set if we
3192 * initiated the authentication. A traditional auth_complete
3193 * event gets always produced as initiator and is also mapped to
3194 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003195 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003196 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003197 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003198
3199 hci_conn_put(conn);
3200
3201unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003202 hci_dev_unlock(hdev);
3203}
3204
Marcel Holtmann41a96212008-07-14 20:13:48 +02003205static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3206{
3207 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3208 struct inquiry_entry *ie;
3209
3210 BT_DBG("%s", hdev->name);
3211
3212 hci_dev_lock(hdev);
3213
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003214 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3215 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003216 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003217
3218 hci_dev_unlock(hdev);
3219}
3220
Szymon Janc2763eda2011-03-22 13:12:22 +01003221static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003222 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003223{
3224 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3225 struct oob_data *data;
3226
3227 BT_DBG("%s", hdev->name);
3228
3229 hci_dev_lock(hdev);
3230
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003231 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003232 goto unlock;
3233
Szymon Janc2763eda2011-03-22 13:12:22 +01003234 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3235 if (data) {
3236 struct hci_cp_remote_oob_data_reply cp;
3237
3238 bacpy(&cp.bdaddr, &ev->bdaddr);
3239 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3240 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3241
3242 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3243 &cp);
3244 } else {
3245 struct hci_cp_remote_oob_data_neg_reply cp;
3246
3247 bacpy(&cp.bdaddr, &ev->bdaddr);
3248 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3249 &cp);
3250 }
3251
Szymon Jance1ba1f12011-04-06 13:01:59 +02003252unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003253 hci_dev_unlock(hdev);
3254}
3255
Ville Tervofcd89c02011-02-10 22:38:47 -03003256static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3257{
3258 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3259 struct hci_conn *conn;
3260
3261 BT_DBG("%s status %d", hdev->name, ev->status);
3262
3263 hci_dev_lock(hdev);
3264
3265 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003266 if (!conn) {
3267 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3268 if (!conn) {
3269 BT_ERR("No memory for new connection");
3270 hci_dev_unlock(hdev);
3271 return;
3272 }
Andre Guedes29b79882011-05-31 14:20:54 -03003273
3274 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003275 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003276
3277 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003278 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3279 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003280 hci_proto_connect_cfm(conn, ev->status);
3281 conn->state = BT_CLOSED;
3282 hci_conn_del(conn);
3283 goto unlock;
3284 }
3285
Johan Hedbergb644ba32012-01-17 21:48:47 +02003286 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3287 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003288 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003289
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003290 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003291 conn->handle = __le16_to_cpu(ev->handle);
3292 conn->state = BT_CONNECTED;
3293
3294 hci_conn_hold_device(conn);
3295 hci_conn_add_sysfs(conn);
3296
3297 hci_proto_connect_cfm(conn, ev->status);
3298
3299unlock:
3300 hci_dev_unlock(hdev);
3301}
3302
Andre Guedes9aa04c92011-05-26 16:23:51 -03003303static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3304 struct sk_buff *skb)
3305{
Andre Guedese95beb42011-09-26 20:48:35 -03003306 u8 num_reports = skb->data[0];
3307 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003308 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003309
3310 hci_dev_lock(hdev);
3311
Andre Guedese95beb42011-09-26 20:48:35 -03003312 while (num_reports--) {
3313 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003314
Andre Guedes9aa04c92011-05-26 16:23:51 -03003315 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003316
Andre Guedes3c9e9192012-01-10 18:20:50 -03003317 rssi = ev->data[ev->length];
3318 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003319 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003320
Andre Guedese95beb42011-09-26 20:48:35 -03003321 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003322 }
3323
3324 hci_dev_unlock(hdev);
3325}
3326
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003327static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3328 struct sk_buff *skb)
3329{
3330 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3331 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003332 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003333 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003334 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003335
3336 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3337
3338 hci_dev_lock(hdev);
3339
3340 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003341 if (conn == NULL)
3342 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003343
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003344 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3345 if (ltk == NULL)
3346 goto not_found;
3347
3348 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003349 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003350
3351 if (ltk->authenticated)
3352 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003353
3354 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3355
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003356 if (ltk->type & HCI_SMP_STK) {
3357 list_del(&ltk->list);
3358 kfree(ltk);
3359 }
3360
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003361 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003362
3363 return;
3364
3365not_found:
3366 neg.handle = ev->handle;
3367 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3368 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003369}
3370
Ville Tervofcd89c02011-02-10 22:38:47 -03003371static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3372{
3373 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3374
3375 skb_pull(skb, sizeof(*le_ev));
3376
3377 switch (le_ev->subevent) {
3378 case HCI_EV_LE_CONN_COMPLETE:
3379 hci_le_conn_complete_evt(hdev, skb);
3380 break;
3381
Andre Guedes9aa04c92011-05-26 16:23:51 -03003382 case HCI_EV_LE_ADVERTISING_REPORT:
3383 hci_le_adv_report_evt(hdev, skb);
3384 break;
3385
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003386 case HCI_EV_LE_LTK_REQ:
3387 hci_le_ltk_request_evt(hdev, skb);
3388 break;
3389
Ville Tervofcd89c02011-02-10 22:38:47 -03003390 default:
3391 break;
3392 }
3393}
3394
Linus Torvalds1da177e2005-04-16 15:20:36 -07003395void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3396{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003397 struct hci_event_hdr *hdr = (void *) skb->data;
3398 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003399
3400 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3401
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003402 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403 case HCI_EV_INQUIRY_COMPLETE:
3404 hci_inquiry_complete_evt(hdev, skb);
3405 break;
3406
3407 case HCI_EV_INQUIRY_RESULT:
3408 hci_inquiry_result_evt(hdev, skb);
3409 break;
3410
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003411 case HCI_EV_CONN_COMPLETE:
3412 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003413 break;
3414
Linus Torvalds1da177e2005-04-16 15:20:36 -07003415 case HCI_EV_CONN_REQUEST:
3416 hci_conn_request_evt(hdev, skb);
3417 break;
3418
Linus Torvalds1da177e2005-04-16 15:20:36 -07003419 case HCI_EV_DISCONN_COMPLETE:
3420 hci_disconn_complete_evt(hdev, skb);
3421 break;
3422
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423 case HCI_EV_AUTH_COMPLETE:
3424 hci_auth_complete_evt(hdev, skb);
3425 break;
3426
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003427 case HCI_EV_REMOTE_NAME:
3428 hci_remote_name_evt(hdev, skb);
3429 break;
3430
Linus Torvalds1da177e2005-04-16 15:20:36 -07003431 case HCI_EV_ENCRYPT_CHANGE:
3432 hci_encrypt_change_evt(hdev, skb);
3433 break;
3434
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003435 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3436 hci_change_link_key_complete_evt(hdev, skb);
3437 break;
3438
3439 case HCI_EV_REMOTE_FEATURES:
3440 hci_remote_features_evt(hdev, skb);
3441 break;
3442
3443 case HCI_EV_REMOTE_VERSION:
3444 hci_remote_version_evt(hdev, skb);
3445 break;
3446
3447 case HCI_EV_QOS_SETUP_COMPLETE:
3448 hci_qos_setup_complete_evt(hdev, skb);
3449 break;
3450
3451 case HCI_EV_CMD_COMPLETE:
3452 hci_cmd_complete_evt(hdev, skb);
3453 break;
3454
3455 case HCI_EV_CMD_STATUS:
3456 hci_cmd_status_evt(hdev, skb);
3457 break;
3458
3459 case HCI_EV_ROLE_CHANGE:
3460 hci_role_change_evt(hdev, skb);
3461 break;
3462
3463 case HCI_EV_NUM_COMP_PKTS:
3464 hci_num_comp_pkts_evt(hdev, skb);
3465 break;
3466
3467 case HCI_EV_MODE_CHANGE:
3468 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003469 break;
3470
3471 case HCI_EV_PIN_CODE_REQ:
3472 hci_pin_code_request_evt(hdev, skb);
3473 break;
3474
3475 case HCI_EV_LINK_KEY_REQ:
3476 hci_link_key_request_evt(hdev, skb);
3477 break;
3478
3479 case HCI_EV_LINK_KEY_NOTIFY:
3480 hci_link_key_notify_evt(hdev, skb);
3481 break;
3482
3483 case HCI_EV_CLOCK_OFFSET:
3484 hci_clock_offset_evt(hdev, skb);
3485 break;
3486
Marcel Holtmanna8746412008-07-14 20:13:46 +02003487 case HCI_EV_PKT_TYPE_CHANGE:
3488 hci_pkt_type_change_evt(hdev, skb);
3489 break;
3490
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003491 case HCI_EV_PSCAN_REP_MODE:
3492 hci_pscan_rep_mode_evt(hdev, skb);
3493 break;
3494
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003495 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3496 hci_inquiry_result_with_rssi_evt(hdev, skb);
3497 break;
3498
3499 case HCI_EV_REMOTE_EXT_FEATURES:
3500 hci_remote_ext_features_evt(hdev, skb);
3501 break;
3502
3503 case HCI_EV_SYNC_CONN_COMPLETE:
3504 hci_sync_conn_complete_evt(hdev, skb);
3505 break;
3506
3507 case HCI_EV_SYNC_CONN_CHANGED:
3508 hci_sync_conn_changed_evt(hdev, skb);
3509 break;
3510
Marcel Holtmann04837f62006-07-03 10:02:33 +02003511 case HCI_EV_SNIFF_SUBRATE:
3512 hci_sniff_subrate_evt(hdev, skb);
3513 break;
3514
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003515 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3516 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003517 break;
3518
Marcel Holtmann04936842008-07-14 20:13:48 +02003519 case HCI_EV_IO_CAPA_REQUEST:
3520 hci_io_capa_request_evt(hdev, skb);
3521 break;
3522
Johan Hedberg03b555e2011-01-04 15:40:05 +02003523 case HCI_EV_IO_CAPA_REPLY:
3524 hci_io_capa_reply_evt(hdev, skb);
3525 break;
3526
Johan Hedberga5c29682011-02-19 12:05:57 -03003527 case HCI_EV_USER_CONFIRM_REQUEST:
3528 hci_user_confirm_request_evt(hdev, skb);
3529 break;
3530
Brian Gix1143d452011-11-23 08:28:34 -08003531 case HCI_EV_USER_PASSKEY_REQUEST:
3532 hci_user_passkey_request_evt(hdev, skb);
3533 break;
3534
Marcel Holtmann04936842008-07-14 20:13:48 +02003535 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3536 hci_simple_pair_complete_evt(hdev, skb);
3537 break;
3538
Marcel Holtmann41a96212008-07-14 20:13:48 +02003539 case HCI_EV_REMOTE_HOST_FEATURES:
3540 hci_remote_host_features_evt(hdev, skb);
3541 break;
3542
Ville Tervofcd89c02011-02-10 22:38:47 -03003543 case HCI_EV_LE_META:
3544 hci_le_meta_evt(hdev, skb);
3545 break;
3546
Szymon Janc2763eda2011-03-22 13:12:22 +01003547 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3548 hci_remote_oob_data_request_evt(hdev, skb);
3549 break;
3550
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003551 case HCI_EV_NUM_COMP_BLOCKS:
3552 hci_num_comp_blocks_evt(hdev, skb);
3553 break;
3554
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003555 default:
3556 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003557 break;
3558 }
3559
3560 kfree_skb(skb);
3561 hdev->stat.evt_rx++;
3562}