blob: df2615d59eb058505c61e12485f6a628fdd00dc1 [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 Emeltchenkoe61ef492011-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);
Ram Malovanya431bd52012-07-19 10:26:09 +03001360 if (!e)
1361 return false;
1362
Johan Hedbergb644ba32012-01-17 21:48:47 +02001363 if (hci_resolve_name(hdev, e) == 0) {
1364 e->name_state = NAME_PENDING;
1365 return true;
1366 }
1367
1368 return false;
1369}
1370
1371static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001372 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001373{
1374 struct discovery_state *discov = &hdev->discovery;
1375 struct inquiry_entry *e;
1376
1377 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001378 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1379 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001380
1381 if (discov->state == DISCOVERY_STOPPED)
1382 return;
1383
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001384 if (discov->state == DISCOVERY_STOPPING)
1385 goto discov_complete;
1386
1387 if (discov->state != DISCOVERY_RESOLVING)
1388 return;
1389
1390 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovanya8b8ad62012-07-19 10:26:10 +03001391 /* If the device was not found in a list of found devices names of which
1392 * are pending. there is no need to continue resolving a next name as it
1393 * will be done upon receiving another Remote Name Request Complete
1394 * Event */
1395 if (!e)
1396 return;
1397
1398 list_del(&e->list);
1399 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001400 e->name_state = NAME_KNOWN;
Ram Malovanya8b8ad62012-07-19 10:26:10 +03001401 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1402 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001403 }
1404
Johan Hedbergb644ba32012-01-17 21:48:47 +02001405 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001406 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001407
1408discov_complete:
1409 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1410}
1411
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001412static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1413{
Johan Hedberg127178d2010-11-18 22:22:29 +02001414 struct hci_cp_remote_name_req *cp;
1415 struct hci_conn *conn;
1416
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001417 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001418
1419 /* If successful wait for the name req complete event before
1420 * checking for the need to do authentication */
1421 if (!status)
1422 return;
1423
1424 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1425 if (!cp)
1426 return;
1427
1428 hci_dev_lock(hdev);
1429
1430 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001431
1432 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1433 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1434
Johan Hedberg79c6c702011-04-28 11:28:55 -07001435 if (!conn)
1436 goto unlock;
1437
1438 if (!hci_outgoing_auth_needed(hdev, conn))
1439 goto unlock;
1440
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001441 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001442 struct hci_cp_auth_requested cp;
1443 cp.handle = __cpu_to_le16(conn->handle);
1444 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1445 }
1446
Johan Hedberg79c6c702011-04-28 11:28:55 -07001447unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001448 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001449}
1450
Marcel Holtmann769be972008-07-14 20:13:49 +02001451static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1452{
1453 struct hci_cp_read_remote_features *cp;
1454 struct hci_conn *conn;
1455
1456 BT_DBG("%s status 0x%x", hdev->name, status);
1457
1458 if (!status)
1459 return;
1460
1461 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1462 if (!cp)
1463 return;
1464
1465 hci_dev_lock(hdev);
1466
1467 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1468 if (conn) {
1469 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001470 hci_proto_connect_cfm(conn, status);
1471 hci_conn_put(conn);
1472 }
1473 }
1474
1475 hci_dev_unlock(hdev);
1476}
1477
1478static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1479{
1480 struct hci_cp_read_remote_ext_features *cp;
1481 struct hci_conn *conn;
1482
1483 BT_DBG("%s status 0x%x", hdev->name, status);
1484
1485 if (!status)
1486 return;
1487
1488 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1489 if (!cp)
1490 return;
1491
1492 hci_dev_lock(hdev);
1493
1494 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1495 if (conn) {
1496 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001497 hci_proto_connect_cfm(conn, status);
1498 hci_conn_put(conn);
1499 }
1500 }
1501
1502 hci_dev_unlock(hdev);
1503}
1504
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001505static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1506{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001507 struct hci_cp_setup_sync_conn *cp;
1508 struct hci_conn *acl, *sco;
1509 __u16 handle;
1510
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001511 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001512
1513 if (!status)
1514 return;
1515
1516 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1517 if (!cp)
1518 return;
1519
1520 handle = __le16_to_cpu(cp->handle);
1521
1522 BT_DBG("%s handle %d", hdev->name, handle);
1523
1524 hci_dev_lock(hdev);
1525
1526 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001527 if (acl) {
1528 sco = acl->link;
1529 if (sco) {
1530 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001531
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001532 hci_proto_connect_cfm(sco, status);
1533 hci_conn_del(sco);
1534 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001535 }
1536
1537 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001538}
1539
1540static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1541{
1542 struct hci_cp_sniff_mode *cp;
1543 struct hci_conn *conn;
1544
1545 BT_DBG("%s status 0x%x", hdev->name, status);
1546
1547 if (!status)
1548 return;
1549
1550 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1551 if (!cp)
1552 return;
1553
1554 hci_dev_lock(hdev);
1555
1556 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001557 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001558 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001559
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001560 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001561 hci_sco_setup(conn, status);
1562 }
1563
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001564 hci_dev_unlock(hdev);
1565}
1566
1567static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1568{
1569 struct hci_cp_exit_sniff_mode *cp;
1570 struct hci_conn *conn;
1571
1572 BT_DBG("%s status 0x%x", hdev->name, status);
1573
1574 if (!status)
1575 return;
1576
1577 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1578 if (!cp)
1579 return;
1580
1581 hci_dev_lock(hdev);
1582
1583 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001584 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001585 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001586
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001587 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001588 hci_sco_setup(conn, status);
1589 }
1590
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001591 hci_dev_unlock(hdev);
1592}
1593
Johan Hedberg88c3df12012-02-09 14:27:38 +02001594static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1595{
1596 struct hci_cp_disconnect *cp;
1597 struct hci_conn *conn;
1598
1599 if (!status)
1600 return;
1601
1602 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1603 if (!cp)
1604 return;
1605
1606 hci_dev_lock(hdev);
1607
1608 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1609 if (conn)
1610 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001611 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001612
1613 hci_dev_unlock(hdev);
1614}
1615
Ville Tervofcd89c02011-02-10 22:38:47 -03001616static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1617{
1618 struct hci_cp_le_create_conn *cp;
1619 struct hci_conn *conn;
1620
1621 BT_DBG("%s status 0x%x", hdev->name, status);
1622
1623 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1624 if (!cp)
1625 return;
1626
1627 hci_dev_lock(hdev);
1628
1629 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1630
1631 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1632 conn);
1633
1634 if (status) {
1635 if (conn && conn->state == BT_CONNECT) {
1636 conn->state = BT_CLOSED;
1637 hci_proto_connect_cfm(conn, status);
1638 hci_conn_del(conn);
1639 }
1640 } else {
1641 if (!conn) {
1642 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001643 if (conn) {
1644 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001645 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001646 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001647 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001648 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001649 }
1650 }
1651
1652 hci_dev_unlock(hdev);
1653}
1654
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001655static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1656{
1657 BT_DBG("%s status 0x%x", hdev->name, status);
1658}
1659
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001660static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1661{
1662 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001663 struct discovery_state *discov = &hdev->discovery;
1664 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001665
1666 BT_DBG("%s status %d", hdev->name, status);
1667
Johan Hedberg23bb5762010-12-21 23:01:27 +02001668 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001669
1670 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001671
1672 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1673 return;
1674
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001675 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001676 return;
1677
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001678 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001679
Andre Guedes343f9352012-02-17 20:39:37 -03001680 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001681 goto unlock;
1682
1683 if (list_empty(&discov->resolve)) {
1684 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1685 goto unlock;
1686 }
1687
1688 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1689 if (e && hci_resolve_name(hdev, e) == 0) {
1690 e->name_state = NAME_PENDING;
1691 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1692 } else {
1693 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1694 }
1695
1696unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001697 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001698}
1699
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1701{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001702 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001703 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 int num_rsp = *((__u8 *) skb->data);
1705
1706 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1707
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001708 if (!num_rsp)
1709 return;
1710
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001712
Johan Hedberge17acd42011-03-30 23:57:16 +03001713 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001714 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001715
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 bacpy(&data.bdaddr, &info->bdaddr);
1717 data.pscan_rep_mode = info->pscan_rep_mode;
1718 data.pscan_period_mode = info->pscan_period_mode;
1719 data.pscan_mode = info->pscan_mode;
1720 memcpy(data.dev_class, info->dev_class, 3);
1721 data.clock_offset = info->clock_offset;
1722 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001723 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001724
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001725 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001726 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001727 info->dev_class, 0, !name_known, ssp, NULL,
1728 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001730
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 hci_dev_unlock(hdev);
1732}
1733
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001734static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001736 struct hci_ev_conn_complete *ev = (void *) skb->data;
1737 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001739 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001740
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001742
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001743 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001744 if (!conn) {
1745 if (ev->link_type != SCO_LINK)
1746 goto unlock;
1747
1748 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1749 if (!conn)
1750 goto unlock;
1751
1752 conn->type = SCO_LINK;
1753 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001754
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001755 if (!ev->status) {
1756 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001757
1758 if (conn->type == ACL_LINK) {
1759 conn->state = BT_CONFIG;
1760 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001761 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001762 } else
1763 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001764
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001765 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001766 hci_conn_add_sysfs(conn);
1767
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001768 if (test_bit(HCI_AUTH, &hdev->flags))
1769 conn->link_mode |= HCI_LM_AUTH;
1770
1771 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1772 conn->link_mode |= HCI_LM_ENCRYPT;
1773
1774 /* Get remote features */
1775 if (conn->type == ACL_LINK) {
1776 struct hci_cp_read_remote_features cp;
1777 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001778 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001779 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001780 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001781
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001782 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001783 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001784 struct hci_cp_change_conn_ptype cp;
1785 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001786 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001787 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1788 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001789 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001790 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001791 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001792 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001793 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001794 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001795 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001796
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001797 if (conn->type == ACL_LINK)
1798 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001799
Marcel Holtmann769be972008-07-14 20:13:49 +02001800 if (ev->status) {
1801 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001802 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001803 } else if (ev->link_type != ACL_LINK)
1804 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001805
1806unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001808
1809 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810}
1811
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1813{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001814 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 int mask = hdev->link_mode;
1816
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001817 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1818 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819
1820 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1821
Szymon Janc138d22e2011-02-17 16:44:23 +01001822 if ((mask & HCI_LM_ACCEPT) &&
1823 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001825 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827
1828 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001829
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001830 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1831 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001832 memcpy(ie->data.dev_class, ev->dev_class, 3);
1833
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1835 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001836 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1837 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001838 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839 hci_dev_unlock(hdev);
1840 return;
1841 }
1842 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001843
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 memcpy(conn->dev_class, ev->dev_class, 3);
1845 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001846
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847 hci_dev_unlock(hdev);
1848
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001849 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1850 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001852 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001854 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1855 cp.role = 0x00; /* Become master */
1856 else
1857 cp.role = 0x01; /* Remain slave */
1858
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001859 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1860 &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001861 } else {
1862 struct hci_cp_accept_sync_conn_req cp;
1863
1864 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001865 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001866
1867 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1868 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1869 cp.max_latency = cpu_to_le16(0xffff);
1870 cp.content_format = cpu_to_le16(hdev->voice_setting);
1871 cp.retrans_effort = 0xff;
1872
1873 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001874 sizeof(cp), &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001875 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876 } else {
1877 /* Connection rejected */
1878 struct hci_cp_reject_conn_req cp;
1879
1880 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001881 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001882 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883 }
1884}
1885
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1887{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001888 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001889 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890
1891 BT_DBG("%s status %d", hdev->name, ev->status);
1892
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 hci_dev_lock(hdev);
1894
Marcel Holtmann04837f62006-07-03 10:02:33 +02001895 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001896 if (!conn)
1897 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001898
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001899 if (ev->status == 0)
1900 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901
Johan Hedbergb644ba32012-01-17 21:48:47 +02001902 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1903 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001904 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001905 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1906 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001907 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001908 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001909 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001910 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001911
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001912 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301913 if (conn->type == ACL_LINK && conn->flush_key)
1914 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001915 hci_proto_disconn_cfm(conn, ev->reason);
1916 hci_conn_del(conn);
1917 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001918
1919unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 hci_dev_unlock(hdev);
1921}
1922
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001923static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1924{
1925 struct hci_ev_auth_complete *ev = (void *) skb->data;
1926 struct hci_conn *conn;
1927
1928 BT_DBG("%s status %d", hdev->name, ev->status);
1929
1930 hci_dev_lock(hdev);
1931
1932 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001933 if (!conn)
1934 goto unlock;
1935
1936 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001937 if (!hci_conn_ssp_enabled(conn) &&
1938 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001939 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001940 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001941 conn->link_mode |= HCI_LM_AUTH;
1942 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001943 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001944 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001945 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001946 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001947 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001948
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001949 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1950 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001951
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001952 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001953 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001954 struct hci_cp_set_conn_encrypt cp;
1955 cp.handle = ev->handle;
1956 cp.encrypt = 0x01;
1957 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1958 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001959 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001960 conn->state = BT_CONNECTED;
1961 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001962 hci_conn_put(conn);
1963 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001964 } else {
1965 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001966
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001967 hci_conn_hold(conn);
1968 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1969 hci_conn_put(conn);
1970 }
1971
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001972 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001973 if (!ev->status) {
1974 struct hci_cp_set_conn_encrypt cp;
1975 cp.handle = ev->handle;
1976 cp.encrypt = 0x01;
1977 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1978 &cp);
1979 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001980 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001981 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001982 }
1983 }
1984
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001985unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001986 hci_dev_unlock(hdev);
1987}
1988
1989static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1990{
Johan Hedberg127178d2010-11-18 22:22:29 +02001991 struct hci_ev_remote_name *ev = (void *) skb->data;
1992 struct hci_conn *conn;
1993
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001994 BT_DBG("%s", hdev->name);
1995
1996 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001997
1998 hci_dev_lock(hdev);
1999
2000 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002001
2002 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2003 goto check_auth;
2004
2005 if (ev->status == 0)
2006 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002007 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002008 else
2009 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2010
2011check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002012 if (!conn)
2013 goto unlock;
2014
2015 if (!hci_outgoing_auth_needed(hdev, conn))
2016 goto unlock;
2017
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002018 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002019 struct hci_cp_auth_requested cp;
2020 cp.handle = __cpu_to_le16(conn->handle);
2021 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2022 }
2023
Johan Hedberg79c6c702011-04-28 11:28:55 -07002024unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002025 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002026}
2027
2028static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2029{
2030 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2031 struct hci_conn *conn;
2032
2033 BT_DBG("%s status %d", hdev->name, ev->status);
2034
2035 hci_dev_lock(hdev);
2036
2037 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2038 if (conn) {
2039 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002040 if (ev->encrypt) {
2041 /* Encryption implies authentication */
2042 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002043 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002044 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002045 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002046 conn->link_mode &= ~HCI_LM_ENCRYPT;
2047 }
2048
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002049 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002050
Gustavo Padovana7d77232012-05-13 03:20:07 -03002051 if (ev->status && conn->state == BT_CONNECTED) {
2052 hci_acl_disconn(conn, 0x13);
2053 hci_conn_put(conn);
2054 goto unlock;
2055 }
2056
Marcel Holtmannf8558552008-07-14 20:13:49 +02002057 if (conn->state == BT_CONFIG) {
2058 if (!ev->status)
2059 conn->state = BT_CONNECTED;
2060
2061 hci_proto_connect_cfm(conn, ev->status);
2062 hci_conn_put(conn);
2063 } else
2064 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002065 }
2066
Gustavo Padovana7d77232012-05-13 03:20:07 -03002067unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002068 hci_dev_unlock(hdev);
2069}
2070
2071static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2072{
2073 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2074 struct hci_conn *conn;
2075
2076 BT_DBG("%s status %d", hdev->name, ev->status);
2077
2078 hci_dev_lock(hdev);
2079
2080 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2081 if (conn) {
2082 if (!ev->status)
2083 conn->link_mode |= HCI_LM_SECURE;
2084
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002085 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002086
2087 hci_key_change_cfm(conn, ev->status);
2088 }
2089
2090 hci_dev_unlock(hdev);
2091}
2092
2093static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2094{
2095 struct hci_ev_remote_features *ev = (void *) skb->data;
2096 struct hci_conn *conn;
2097
2098 BT_DBG("%s status %d", hdev->name, ev->status);
2099
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002100 hci_dev_lock(hdev);
2101
2102 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002103 if (!conn)
2104 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002105
Johan Hedbergccd556f2010-11-10 17:11:51 +02002106 if (!ev->status)
2107 memcpy(conn->features, ev->features, 8);
2108
2109 if (conn->state != BT_CONFIG)
2110 goto unlock;
2111
2112 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2113 struct hci_cp_read_remote_ext_features cp;
2114 cp.handle = ev->handle;
2115 cp.page = 0x01;
2116 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002117 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002118 goto unlock;
2119 }
2120
Johan Hedberg671267b2012-05-12 16:11:50 -03002121 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002122 struct hci_cp_remote_name_req cp;
2123 memset(&cp, 0, sizeof(cp));
2124 bacpy(&cp.bdaddr, &conn->dst);
2125 cp.pscan_rep_mode = 0x02;
2126 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002127 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2128 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002129 conn->dst_type, 0, NULL, 0,
2130 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002131
Johan Hedberg127178d2010-11-18 22:22:29 +02002132 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002133 conn->state = BT_CONNECTED;
2134 hci_proto_connect_cfm(conn, ev->status);
2135 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002136 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002137
Johan Hedbergccd556f2010-11-10 17:11:51 +02002138unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002139 hci_dev_unlock(hdev);
2140}
2141
2142static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2143{
2144 BT_DBG("%s", hdev->name);
2145}
2146
2147static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2148{
2149 BT_DBG("%s", hdev->name);
2150}
2151
2152static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2153{
2154 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2155 __u16 opcode;
2156
2157 skb_pull(skb, sizeof(*ev));
2158
2159 opcode = __le16_to_cpu(ev->opcode);
2160
2161 switch (opcode) {
2162 case HCI_OP_INQUIRY_CANCEL:
2163 hci_cc_inquiry_cancel(hdev, skb);
2164 break;
2165
2166 case HCI_OP_EXIT_PERIODIC_INQ:
2167 hci_cc_exit_periodic_inq(hdev, skb);
2168 break;
2169
2170 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2171 hci_cc_remote_name_req_cancel(hdev, skb);
2172 break;
2173
2174 case HCI_OP_ROLE_DISCOVERY:
2175 hci_cc_role_discovery(hdev, skb);
2176 break;
2177
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002178 case HCI_OP_READ_LINK_POLICY:
2179 hci_cc_read_link_policy(hdev, skb);
2180 break;
2181
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002182 case HCI_OP_WRITE_LINK_POLICY:
2183 hci_cc_write_link_policy(hdev, skb);
2184 break;
2185
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002186 case HCI_OP_READ_DEF_LINK_POLICY:
2187 hci_cc_read_def_link_policy(hdev, skb);
2188 break;
2189
2190 case HCI_OP_WRITE_DEF_LINK_POLICY:
2191 hci_cc_write_def_link_policy(hdev, skb);
2192 break;
2193
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002194 case HCI_OP_RESET:
2195 hci_cc_reset(hdev, skb);
2196 break;
2197
2198 case HCI_OP_WRITE_LOCAL_NAME:
2199 hci_cc_write_local_name(hdev, skb);
2200 break;
2201
2202 case HCI_OP_READ_LOCAL_NAME:
2203 hci_cc_read_local_name(hdev, skb);
2204 break;
2205
2206 case HCI_OP_WRITE_AUTH_ENABLE:
2207 hci_cc_write_auth_enable(hdev, skb);
2208 break;
2209
2210 case HCI_OP_WRITE_ENCRYPT_MODE:
2211 hci_cc_write_encrypt_mode(hdev, skb);
2212 break;
2213
2214 case HCI_OP_WRITE_SCAN_ENABLE:
2215 hci_cc_write_scan_enable(hdev, skb);
2216 break;
2217
2218 case HCI_OP_READ_CLASS_OF_DEV:
2219 hci_cc_read_class_of_dev(hdev, skb);
2220 break;
2221
2222 case HCI_OP_WRITE_CLASS_OF_DEV:
2223 hci_cc_write_class_of_dev(hdev, skb);
2224 break;
2225
2226 case HCI_OP_READ_VOICE_SETTING:
2227 hci_cc_read_voice_setting(hdev, skb);
2228 break;
2229
2230 case HCI_OP_WRITE_VOICE_SETTING:
2231 hci_cc_write_voice_setting(hdev, skb);
2232 break;
2233
2234 case HCI_OP_HOST_BUFFER_SIZE:
2235 hci_cc_host_buffer_size(hdev, skb);
2236 break;
2237
Marcel Holtmann333140b2008-07-14 20:13:48 +02002238 case HCI_OP_WRITE_SSP_MODE:
2239 hci_cc_write_ssp_mode(hdev, skb);
2240 break;
2241
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002242 case HCI_OP_READ_LOCAL_VERSION:
2243 hci_cc_read_local_version(hdev, skb);
2244 break;
2245
2246 case HCI_OP_READ_LOCAL_COMMANDS:
2247 hci_cc_read_local_commands(hdev, skb);
2248 break;
2249
2250 case HCI_OP_READ_LOCAL_FEATURES:
2251 hci_cc_read_local_features(hdev, skb);
2252 break;
2253
Andre Guedes971e3a42011-06-30 19:20:52 -03002254 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2255 hci_cc_read_local_ext_features(hdev, skb);
2256 break;
2257
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002258 case HCI_OP_READ_BUFFER_SIZE:
2259 hci_cc_read_buffer_size(hdev, skb);
2260 break;
2261
2262 case HCI_OP_READ_BD_ADDR:
2263 hci_cc_read_bd_addr(hdev, skb);
2264 break;
2265
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002266 case HCI_OP_READ_DATA_BLOCK_SIZE:
2267 hci_cc_read_data_block_size(hdev, skb);
2268 break;
2269
Johan Hedberg23bb5762010-12-21 23:01:27 +02002270 case HCI_OP_WRITE_CA_TIMEOUT:
2271 hci_cc_write_ca_timeout(hdev, skb);
2272 break;
2273
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002274 case HCI_OP_READ_FLOW_CONTROL_MODE:
2275 hci_cc_read_flow_control_mode(hdev, skb);
2276 break;
2277
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002278 case HCI_OP_READ_LOCAL_AMP_INFO:
2279 hci_cc_read_local_amp_info(hdev, skb);
2280 break;
2281
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002282 case HCI_OP_DELETE_STORED_LINK_KEY:
2283 hci_cc_delete_stored_link_key(hdev, skb);
2284 break;
2285
Johan Hedbergd5859e22011-01-25 01:19:58 +02002286 case HCI_OP_SET_EVENT_MASK:
2287 hci_cc_set_event_mask(hdev, skb);
2288 break;
2289
2290 case HCI_OP_WRITE_INQUIRY_MODE:
2291 hci_cc_write_inquiry_mode(hdev, skb);
2292 break;
2293
2294 case HCI_OP_READ_INQ_RSP_TX_POWER:
2295 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2296 break;
2297
2298 case HCI_OP_SET_EVENT_FLT:
2299 hci_cc_set_event_flt(hdev, skb);
2300 break;
2301
Johan Hedberg980e1a52011-01-22 06:10:07 +02002302 case HCI_OP_PIN_CODE_REPLY:
2303 hci_cc_pin_code_reply(hdev, skb);
2304 break;
2305
2306 case HCI_OP_PIN_CODE_NEG_REPLY:
2307 hci_cc_pin_code_neg_reply(hdev, skb);
2308 break;
2309
Szymon Jancc35938b2011-03-22 13:12:21 +01002310 case HCI_OP_READ_LOCAL_OOB_DATA:
2311 hci_cc_read_local_oob_data_reply(hdev, skb);
2312 break;
2313
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002314 case HCI_OP_LE_READ_BUFFER_SIZE:
2315 hci_cc_le_read_buffer_size(hdev, skb);
2316 break;
2317
Johan Hedberga5c29682011-02-19 12:05:57 -03002318 case HCI_OP_USER_CONFIRM_REPLY:
2319 hci_cc_user_confirm_reply(hdev, skb);
2320 break;
2321
2322 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2323 hci_cc_user_confirm_neg_reply(hdev, skb);
2324 break;
2325
Brian Gix1143d452011-11-23 08:28:34 -08002326 case HCI_OP_USER_PASSKEY_REPLY:
2327 hci_cc_user_passkey_reply(hdev, skb);
2328 break;
2329
2330 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2331 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002332 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002333
2334 case HCI_OP_LE_SET_SCAN_PARAM:
2335 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002336 break;
2337
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002338 case HCI_OP_LE_SET_SCAN_ENABLE:
2339 hci_cc_le_set_scan_enable(hdev, skb);
2340 break;
2341
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002342 case HCI_OP_LE_LTK_REPLY:
2343 hci_cc_le_ltk_reply(hdev, skb);
2344 break;
2345
2346 case HCI_OP_LE_LTK_NEG_REPLY:
2347 hci_cc_le_ltk_neg_reply(hdev, skb);
2348 break;
2349
Andre Guedesf9b49302011-06-30 19:20:53 -03002350 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2351 hci_cc_write_le_host_supported(hdev, skb);
2352 break;
2353
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002354 default:
2355 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2356 break;
2357 }
2358
Ville Tervo6bd32322011-02-16 16:32:41 +02002359 if (ev->opcode != HCI_OP_NOP)
2360 del_timer(&hdev->cmd_timer);
2361
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002362 if (ev->ncmd) {
2363 atomic_set(&hdev->cmd_cnt, 1);
2364 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002365 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002366 }
2367}
2368
2369static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2370{
2371 struct hci_ev_cmd_status *ev = (void *) skb->data;
2372 __u16 opcode;
2373
2374 skb_pull(skb, sizeof(*ev));
2375
2376 opcode = __le16_to_cpu(ev->opcode);
2377
2378 switch (opcode) {
2379 case HCI_OP_INQUIRY:
2380 hci_cs_inquiry(hdev, ev->status);
2381 break;
2382
2383 case HCI_OP_CREATE_CONN:
2384 hci_cs_create_conn(hdev, ev->status);
2385 break;
2386
2387 case HCI_OP_ADD_SCO:
2388 hci_cs_add_sco(hdev, ev->status);
2389 break;
2390
Marcel Holtmannf8558552008-07-14 20:13:49 +02002391 case HCI_OP_AUTH_REQUESTED:
2392 hci_cs_auth_requested(hdev, ev->status);
2393 break;
2394
2395 case HCI_OP_SET_CONN_ENCRYPT:
2396 hci_cs_set_conn_encrypt(hdev, ev->status);
2397 break;
2398
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002399 case HCI_OP_REMOTE_NAME_REQ:
2400 hci_cs_remote_name_req(hdev, ev->status);
2401 break;
2402
Marcel Holtmann769be972008-07-14 20:13:49 +02002403 case HCI_OP_READ_REMOTE_FEATURES:
2404 hci_cs_read_remote_features(hdev, ev->status);
2405 break;
2406
2407 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2408 hci_cs_read_remote_ext_features(hdev, ev->status);
2409 break;
2410
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002411 case HCI_OP_SETUP_SYNC_CONN:
2412 hci_cs_setup_sync_conn(hdev, ev->status);
2413 break;
2414
2415 case HCI_OP_SNIFF_MODE:
2416 hci_cs_sniff_mode(hdev, ev->status);
2417 break;
2418
2419 case HCI_OP_EXIT_SNIFF_MODE:
2420 hci_cs_exit_sniff_mode(hdev, ev->status);
2421 break;
2422
Johan Hedberg8962ee72011-01-20 12:40:27 +02002423 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002424 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002425 break;
2426
Ville Tervofcd89c02011-02-10 22:38:47 -03002427 case HCI_OP_LE_CREATE_CONN:
2428 hci_cs_le_create_conn(hdev, ev->status);
2429 break;
2430
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002431 case HCI_OP_LE_START_ENC:
2432 hci_cs_le_start_enc(hdev, ev->status);
2433 break;
2434
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002435 default:
2436 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2437 break;
2438 }
2439
Ville Tervo6bd32322011-02-16 16:32:41 +02002440 if (ev->opcode != HCI_OP_NOP)
2441 del_timer(&hdev->cmd_timer);
2442
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002443 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002444 atomic_set(&hdev->cmd_cnt, 1);
2445 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002446 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002447 }
2448}
2449
2450static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2451{
2452 struct hci_ev_role_change *ev = (void *) skb->data;
2453 struct hci_conn *conn;
2454
2455 BT_DBG("%s status %d", hdev->name, ev->status);
2456
2457 hci_dev_lock(hdev);
2458
2459 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2460 if (conn) {
2461 if (!ev->status) {
2462 if (ev->role)
2463 conn->link_mode &= ~HCI_LM_MASTER;
2464 else
2465 conn->link_mode |= HCI_LM_MASTER;
2466 }
2467
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002468 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002469
2470 hci_role_switch_cfm(conn, ev->status, ev->role);
2471 }
2472
2473 hci_dev_unlock(hdev);
2474}
2475
Linus Torvalds1da177e2005-04-16 15:20:36 -07002476static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2477{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002478 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002479 int i;
2480
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002481 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2482 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2483 return;
2484 }
2485
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002486 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2487 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002488 BT_DBG("%s bad parameters", hdev->name);
2489 return;
2490 }
2491
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002492 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2493
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002494 for (i = 0; i < ev->num_hndl; i++) {
2495 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496 struct hci_conn *conn;
2497 __u16 handle, count;
2498
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002499 handle = __le16_to_cpu(info->handle);
2500 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501
2502 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002503 if (!conn)
2504 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002506 conn->sent -= count;
2507
2508 switch (conn->type) {
2509 case ACL_LINK:
2510 hdev->acl_cnt += count;
2511 if (hdev->acl_cnt > hdev->acl_pkts)
2512 hdev->acl_cnt = hdev->acl_pkts;
2513 break;
2514
2515 case LE_LINK:
2516 if (hdev->le_pkts) {
2517 hdev->le_cnt += count;
2518 if (hdev->le_cnt > hdev->le_pkts)
2519 hdev->le_cnt = hdev->le_pkts;
2520 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002521 hdev->acl_cnt += count;
2522 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523 hdev->acl_cnt = hdev->acl_pkts;
2524 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002525 break;
2526
2527 case SCO_LINK:
2528 hdev->sco_cnt += count;
2529 if (hdev->sco_cnt > hdev->sco_pkts)
2530 hdev->sco_cnt = hdev->sco_pkts;
2531 break;
2532
2533 default:
2534 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2535 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536 }
2537 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002538
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002539 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002540}
2541
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002542static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002543 struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002544{
2545 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2546 int i;
2547
2548 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2549 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2550 return;
2551 }
2552
2553 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2554 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2555 BT_DBG("%s bad parameters", hdev->name);
2556 return;
2557 }
2558
2559 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2560 ev->num_hndl);
2561
2562 for (i = 0; i < ev->num_hndl; i++) {
2563 struct hci_comp_blocks_info *info = &ev->handles[i];
2564 struct hci_conn *conn;
2565 __u16 handle, block_count;
2566
2567 handle = __le16_to_cpu(info->handle);
2568 block_count = __le16_to_cpu(info->blocks);
2569
2570 conn = hci_conn_hash_lookup_handle(hdev, handle);
2571 if (!conn)
2572 continue;
2573
2574 conn->sent -= block_count;
2575
2576 switch (conn->type) {
2577 case ACL_LINK:
2578 hdev->block_cnt += block_count;
2579 if (hdev->block_cnt > hdev->num_blocks)
2580 hdev->block_cnt = hdev->num_blocks;
2581 break;
2582
2583 default:
2584 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2585 break;
2586 }
2587 }
2588
2589 queue_work(hdev->workqueue, &hdev->tx_work);
2590}
2591
Marcel Holtmann04837f62006-07-03 10:02:33 +02002592static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002593{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002594 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002595 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596
2597 BT_DBG("%s status %d", hdev->name, ev->status);
2598
2599 hci_dev_lock(hdev);
2600
Marcel Holtmann04837f62006-07-03 10:02:33 +02002601 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2602 if (conn) {
2603 conn->mode = ev->mode;
2604 conn->interval = __le16_to_cpu(ev->interval);
2605
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002606 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002607 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002608 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002609 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002610 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002611 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002612
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002613 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002614 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002615 }
2616
2617 hci_dev_unlock(hdev);
2618}
2619
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2621{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002622 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2623 struct hci_conn *conn;
2624
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002625 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002626
2627 hci_dev_lock(hdev);
2628
2629 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002630 if (!conn)
2631 goto unlock;
2632
2633 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002634 hci_conn_hold(conn);
2635 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2636 hci_conn_put(conn);
2637 }
2638
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002639 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002640 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2641 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002642 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002643 u8 secure;
2644
2645 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2646 secure = 1;
2647 else
2648 secure = 0;
2649
Johan Hedberg744cf192011-11-08 20:40:14 +02002650 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002651 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002652
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002653unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002654 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655}
2656
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2658{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002659 struct hci_ev_link_key_req *ev = (void *) skb->data;
2660 struct hci_cp_link_key_reply cp;
2661 struct hci_conn *conn;
2662 struct link_key *key;
2663
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002664 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002665
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002666 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002667 return;
2668
2669 hci_dev_lock(hdev);
2670
2671 key = hci_find_link_key(hdev, &ev->bdaddr);
2672 if (!key) {
2673 BT_DBG("%s link key not found for %s", hdev->name,
2674 batostr(&ev->bdaddr));
2675 goto not_found;
2676 }
2677
2678 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2679 batostr(&ev->bdaddr));
2680
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002681 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002682 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002683 BT_DBG("%s ignoring debug key", hdev->name);
2684 goto not_found;
2685 }
2686
2687 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002688 if (conn) {
2689 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2690 conn->auth_type != 0xff &&
2691 (conn->auth_type & 0x01)) {
2692 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2693 goto not_found;
2694 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002695
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002696 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2697 conn->pending_sec_level == BT_SECURITY_HIGH) {
2698 BT_DBG("%s ignoring key unauthenticated for high \
2699 security", hdev->name);
2700 goto not_found;
2701 }
2702
2703 conn->key_type = key->type;
2704 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002705 }
2706
2707 bacpy(&cp.bdaddr, &ev->bdaddr);
2708 memcpy(cp.link_key, key->val, 16);
2709
2710 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2711
2712 hci_dev_unlock(hdev);
2713
2714 return;
2715
2716not_found:
2717 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2718 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719}
2720
Linus Torvalds1da177e2005-04-16 15:20:36 -07002721static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2722{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002723 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2724 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002725 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002726
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002727 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002728
2729 hci_dev_lock(hdev);
2730
2731 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2732 if (conn) {
2733 hci_conn_hold(conn);
2734 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002735 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002736
2737 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2738 conn->key_type = ev->key_type;
2739
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002740 hci_conn_put(conn);
2741 }
2742
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002743 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002744 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002745 ev->key_type, pin_len);
2746
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002747 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748}
2749
Marcel Holtmann04837f62006-07-03 10:02:33 +02002750static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2751{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002752 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002753 struct hci_conn *conn;
2754
2755 BT_DBG("%s status %d", hdev->name, ev->status);
2756
2757 hci_dev_lock(hdev);
2758
2759 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760 if (conn && !ev->status) {
2761 struct inquiry_entry *ie;
2762
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002763 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2764 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765 ie->data.clock_offset = ev->clock_offset;
2766 ie->timestamp = jiffies;
2767 }
2768 }
2769
2770 hci_dev_unlock(hdev);
2771}
2772
Marcel Holtmanna8746412008-07-14 20:13:46 +02002773static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2774{
2775 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2776 struct hci_conn *conn;
2777
2778 BT_DBG("%s status %d", hdev->name, ev->status);
2779
2780 hci_dev_lock(hdev);
2781
2782 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2783 if (conn && !ev->status)
2784 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2785
2786 hci_dev_unlock(hdev);
2787}
2788
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002789static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2790{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002791 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002792 struct inquiry_entry *ie;
2793
2794 BT_DBG("%s", hdev->name);
2795
2796 hci_dev_lock(hdev);
2797
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002798 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2799 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002800 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2801 ie->timestamp = jiffies;
2802 }
2803
2804 hci_dev_unlock(hdev);
2805}
2806
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002807static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2808{
2809 struct inquiry_data data;
2810 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002811 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002812
2813 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2814
2815 if (!num_rsp)
2816 return;
2817
2818 hci_dev_lock(hdev);
2819
2820 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002821 struct inquiry_info_with_rssi_and_pscan_mode *info;
2822 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002823
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 = info->pscan_mode;
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
2834 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002835 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002836 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002837 info->dev_class, info->rssi,
2838 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002839 }
2840 } else {
2841 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2842
Johan Hedberge17acd42011-03-30 23:57:16 +03002843 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002844 bacpy(&data.bdaddr, &info->bdaddr);
2845 data.pscan_rep_mode = info->pscan_rep_mode;
2846 data.pscan_period_mode = info->pscan_period_mode;
2847 data.pscan_mode = 0x00;
2848 memcpy(data.dev_class, info->dev_class, 3);
2849 data.clock_offset = info->clock_offset;
2850 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002851 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002852 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002853 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002854 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002855 info->dev_class, info->rssi,
2856 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002857 }
2858 }
2859
2860 hci_dev_unlock(hdev);
2861}
2862
2863static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2864{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002865 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2866 struct hci_conn *conn;
2867
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002868 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002869
Marcel Holtmann41a96212008-07-14 20:13:48 +02002870 hci_dev_lock(hdev);
2871
2872 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002873 if (!conn)
2874 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002875
Johan Hedbergccd556f2010-11-10 17:11:51 +02002876 if (!ev->status && ev->page == 0x01) {
2877 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002878
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002879 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2880 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002881 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002882
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002883 if (ev->features[0] & LMP_HOST_SSP)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002884 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002885 }
2886
Johan Hedbergccd556f2010-11-10 17:11:51 +02002887 if (conn->state != BT_CONFIG)
2888 goto unlock;
2889
Johan Hedberg671267b2012-05-12 16:11:50 -03002890 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002891 struct hci_cp_remote_name_req cp;
2892 memset(&cp, 0, sizeof(cp));
2893 bacpy(&cp.bdaddr, &conn->dst);
2894 cp.pscan_rep_mode = 0x02;
2895 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002896 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2897 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002898 conn->dst_type, 0, NULL, 0,
2899 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002900
Johan Hedberg127178d2010-11-18 22:22:29 +02002901 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002902 conn->state = BT_CONNECTED;
2903 hci_proto_connect_cfm(conn, ev->status);
2904 hci_conn_put(conn);
2905 }
2906
2907unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002908 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002909}
2910
2911static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2912{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002913 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2914 struct hci_conn *conn;
2915
2916 BT_DBG("%s status %d", hdev->name, ev->status);
2917
2918 hci_dev_lock(hdev);
2919
2920 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002921 if (!conn) {
2922 if (ev->link_type == ESCO_LINK)
2923 goto unlock;
2924
2925 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2926 if (!conn)
2927 goto unlock;
2928
2929 conn->type = SCO_LINK;
2930 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002931
Marcel Holtmann732547f2009-04-19 19:14:14 +02002932 switch (ev->status) {
2933 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002934 conn->handle = __le16_to_cpu(ev->handle);
2935 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002936
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002937 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002938 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002939 break;
2940
Stephen Coe705e5712010-02-16 11:29:44 -05002941 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002942 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002943 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002944 case 0x1f: /* Unspecified error */
2945 if (conn->out && conn->attempt < 2) {
2946 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2947 (hdev->esco_type & EDR_ESCO_MASK);
2948 hci_setup_sync(conn, conn->link->handle);
2949 goto unlock;
2950 }
2951 /* fall through */
2952
2953 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002954 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002955 break;
2956 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002957
2958 hci_proto_connect_cfm(conn, ev->status);
2959 if (ev->status)
2960 hci_conn_del(conn);
2961
2962unlock:
2963 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002964}
2965
2966static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2967{
2968 BT_DBG("%s", hdev->name);
2969}
2970
Marcel Holtmann04837f62006-07-03 10:02:33 +02002971static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2972{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002973 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002974
2975 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002976}
2977
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002978static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2979{
2980 struct inquiry_data data;
2981 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2982 int num_rsp = *((__u8 *) skb->data);
2983
2984 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2985
2986 if (!num_rsp)
2987 return;
2988
2989 hci_dev_lock(hdev);
2990
Johan Hedberge17acd42011-03-30 23:57:16 +03002991 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002992 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002993
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002994 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002995 data.pscan_rep_mode = info->pscan_rep_mode;
2996 data.pscan_period_mode = info->pscan_period_mode;
2997 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002998 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002999 data.clock_offset = info->clock_offset;
3000 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003001 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003002
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003003 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003004 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003005 sizeof(info->data),
3006 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003007 else
3008 name_known = true;
3009
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003010 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003011 &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003012 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003013 info->dev_class, info->rssi, !name_known,
3014 ssp, info->data, sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003015 }
3016
3017 hci_dev_unlock(hdev);
3018}
3019
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003020static inline u8 hci_get_auth_req(struct hci_conn *conn)
3021{
3022 /* If remote requests dedicated bonding follow that lead */
3023 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3024 /* If both remote and local IO capabilities allow MITM
3025 * protection then require it, otherwise don't */
3026 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3027 return 0x02;
3028 else
3029 return 0x03;
3030 }
3031
3032 /* If remote requests no-bonding follow that lead */
3033 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003034 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003035
3036 return conn->auth_type;
3037}
3038
Marcel Holtmann04936842008-07-14 20:13:48 +02003039static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3040{
3041 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3042 struct hci_conn *conn;
3043
3044 BT_DBG("%s", hdev->name);
3045
3046 hci_dev_lock(hdev);
3047
3048 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003049 if (!conn)
3050 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003051
Johan Hedberg03b555e2011-01-04 15:40:05 +02003052 hci_conn_hold(conn);
3053
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003054 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003055 goto unlock;
3056
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003057 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003058 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003059 struct hci_cp_io_capability_reply cp;
3060
3061 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303062 /* Change the IO capability from KeyboardDisplay
3063 * to DisplayYesNo as it is not supported by BT spec. */
3064 cp.capability = (conn->io_capability == 0x04) ?
3065 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003066 conn->auth_type = hci_get_auth_req(conn);
3067 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003068
Johan Hedberg58a681e2012-01-16 06:47:28 +02003069 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003070 hci_find_remote_oob_data(hdev, &conn->dst))
3071 cp.oob_data = 0x01;
3072 else
3073 cp.oob_data = 0x00;
3074
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003075 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3076 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003077 } else {
3078 struct hci_cp_io_capability_neg_reply cp;
3079
3080 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003081 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003082
3083 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3084 sizeof(cp), &cp);
3085 }
3086
3087unlock:
3088 hci_dev_unlock(hdev);
3089}
3090
3091static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3092{
3093 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3094 struct hci_conn *conn;
3095
3096 BT_DBG("%s", hdev->name);
3097
3098 hci_dev_lock(hdev);
3099
3100 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3101 if (!conn)
3102 goto unlock;
3103
Johan Hedberg03b555e2011-01-04 15:40:05 +02003104 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003105 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003106 if (ev->oob_data)
3107 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003108
3109unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003110 hci_dev_unlock(hdev);
3111}
3112
Johan Hedberga5c29682011-02-19 12:05:57 -03003113static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3114 struct sk_buff *skb)
3115{
3116 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003117 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003118 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003119
3120 BT_DBG("%s", hdev->name);
3121
3122 hci_dev_lock(hdev);
3123
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003124 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003125 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003126
Johan Hedberg7a828902011-04-28 11:28:53 -07003127 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3128 if (!conn)
3129 goto unlock;
3130
3131 loc_mitm = (conn->auth_type & 0x01);
3132 rem_mitm = (conn->remote_auth & 0x01);
3133
3134 /* If we require MITM but the remote device can't provide that
3135 * (it has NoInputNoOutput) then reject the confirmation
3136 * request. The only exception is when we're dedicated bonding
3137 * initiators (connect_cfm_cb set) since then we always have the MITM
3138 * bit set. */
3139 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3140 BT_DBG("Rejecting request: remote device can't provide MITM");
3141 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3142 sizeof(ev->bdaddr), &ev->bdaddr);
3143 goto unlock;
3144 }
3145
3146 /* If no side requires MITM protection; auto-accept */
3147 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3148 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003149
3150 /* If we're not the initiators request authorization to
3151 * proceed from user space (mgmt_user_confirm with
3152 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003153 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003154 BT_DBG("Confirming auto-accept as acceptor");
3155 confirm_hint = 1;
3156 goto confirm;
3157 }
3158
Johan Hedberg9f616562011-04-28 11:28:54 -07003159 BT_DBG("Auto-accept of user confirmation with %ums delay",
3160 hdev->auto_accept_delay);
3161
3162 if (hdev->auto_accept_delay > 0) {
3163 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3164 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3165 goto unlock;
3166 }
3167
Johan Hedberg7a828902011-04-28 11:28:53 -07003168 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3169 sizeof(ev->bdaddr), &ev->bdaddr);
3170 goto unlock;
3171 }
3172
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003173confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003174 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003175 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003176
3177unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003178 hci_dev_unlock(hdev);
3179}
3180
Brian Gix1143d452011-11-23 08:28:34 -08003181static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3182 struct sk_buff *skb)
3183{
3184 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3185
3186 BT_DBG("%s", hdev->name);
3187
3188 hci_dev_lock(hdev);
3189
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003190 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003191 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003192
3193 hci_dev_unlock(hdev);
3194}
3195
Marcel Holtmann04936842008-07-14 20:13:48 +02003196static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3197{
3198 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3199 struct hci_conn *conn;
3200
3201 BT_DBG("%s", hdev->name);
3202
3203 hci_dev_lock(hdev);
3204
3205 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003206 if (!conn)
3207 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003208
Johan Hedberg2a611692011-02-19 12:06:00 -03003209 /* To avoid duplicate auth_failed events to user space we check
3210 * the HCI_CONN_AUTH_PEND flag which will be set if we
3211 * initiated the authentication. A traditional auth_complete
3212 * event gets always produced as initiator and is also mapped to
3213 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003214 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003215 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003216 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003217
3218 hci_conn_put(conn);
3219
3220unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003221 hci_dev_unlock(hdev);
3222}
3223
Marcel Holtmann41a96212008-07-14 20:13:48 +02003224static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3225{
3226 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3227 struct inquiry_entry *ie;
3228
3229 BT_DBG("%s", hdev->name);
3230
3231 hci_dev_lock(hdev);
3232
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003233 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3234 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003235 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003236
3237 hci_dev_unlock(hdev);
3238}
3239
Szymon Janc2763eda2011-03-22 13:12:22 +01003240static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003241 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003242{
3243 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3244 struct oob_data *data;
3245
3246 BT_DBG("%s", hdev->name);
3247
3248 hci_dev_lock(hdev);
3249
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003250 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003251 goto unlock;
3252
Szymon Janc2763eda2011-03-22 13:12:22 +01003253 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3254 if (data) {
3255 struct hci_cp_remote_oob_data_reply cp;
3256
3257 bacpy(&cp.bdaddr, &ev->bdaddr);
3258 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3259 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3260
3261 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3262 &cp);
3263 } else {
3264 struct hci_cp_remote_oob_data_neg_reply cp;
3265
3266 bacpy(&cp.bdaddr, &ev->bdaddr);
3267 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3268 &cp);
3269 }
3270
Szymon Jance1ba1f12011-04-06 13:01:59 +02003271unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003272 hci_dev_unlock(hdev);
3273}
3274
Ville Tervofcd89c02011-02-10 22:38:47 -03003275static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3276{
3277 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3278 struct hci_conn *conn;
3279
3280 BT_DBG("%s status %d", hdev->name, ev->status);
3281
3282 hci_dev_lock(hdev);
3283
3284 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003285 if (!conn) {
3286 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3287 if (!conn) {
3288 BT_ERR("No memory for new connection");
3289 hci_dev_unlock(hdev);
3290 return;
3291 }
Andre Guedes29b79882011-05-31 14:20:54 -03003292
3293 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003294 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003295
3296 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003297 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3298 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003299 hci_proto_connect_cfm(conn, ev->status);
3300 conn->state = BT_CLOSED;
3301 hci_conn_del(conn);
3302 goto unlock;
3303 }
3304
Johan Hedbergb644ba32012-01-17 21:48:47 +02003305 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3306 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003307 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003308
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003309 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003310 conn->handle = __le16_to_cpu(ev->handle);
3311 conn->state = BT_CONNECTED;
3312
3313 hci_conn_hold_device(conn);
3314 hci_conn_add_sysfs(conn);
3315
3316 hci_proto_connect_cfm(conn, ev->status);
3317
3318unlock:
3319 hci_dev_unlock(hdev);
3320}
3321
Andre Guedes9aa04c92011-05-26 16:23:51 -03003322static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3323 struct sk_buff *skb)
3324{
Andre Guedese95beb42011-09-26 20:48:35 -03003325 u8 num_reports = skb->data[0];
3326 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003327 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003328
3329 hci_dev_lock(hdev);
3330
Andre Guedese95beb42011-09-26 20:48:35 -03003331 while (num_reports--) {
3332 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003333
Andre Guedes9aa04c92011-05-26 16:23:51 -03003334 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003335
Andre Guedes3c9e9192012-01-10 18:20:50 -03003336 rssi = ev->data[ev->length];
3337 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003338 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003339
Andre Guedese95beb42011-09-26 20:48:35 -03003340 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003341 }
3342
3343 hci_dev_unlock(hdev);
3344}
3345
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003346static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3347 struct sk_buff *skb)
3348{
3349 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3350 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003351 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003352 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003353 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003354
3355 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3356
3357 hci_dev_lock(hdev);
3358
3359 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003360 if (conn == NULL)
3361 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003362
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003363 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3364 if (ltk == NULL)
3365 goto not_found;
3366
3367 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003368 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003369
3370 if (ltk->authenticated)
3371 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003372
3373 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3374
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003375 if (ltk->type & HCI_SMP_STK) {
3376 list_del(&ltk->list);
3377 kfree(ltk);
3378 }
3379
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003380 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003381
3382 return;
3383
3384not_found:
3385 neg.handle = ev->handle;
3386 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3387 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003388}
3389
Ville Tervofcd89c02011-02-10 22:38:47 -03003390static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3391{
3392 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3393
3394 skb_pull(skb, sizeof(*le_ev));
3395
3396 switch (le_ev->subevent) {
3397 case HCI_EV_LE_CONN_COMPLETE:
3398 hci_le_conn_complete_evt(hdev, skb);
3399 break;
3400
Andre Guedes9aa04c92011-05-26 16:23:51 -03003401 case HCI_EV_LE_ADVERTISING_REPORT:
3402 hci_le_adv_report_evt(hdev, skb);
3403 break;
3404
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003405 case HCI_EV_LE_LTK_REQ:
3406 hci_le_ltk_request_evt(hdev, skb);
3407 break;
3408
Ville Tervofcd89c02011-02-10 22:38:47 -03003409 default:
3410 break;
3411 }
3412}
3413
Linus Torvalds1da177e2005-04-16 15:20:36 -07003414void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3415{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003416 struct hci_event_hdr *hdr = (void *) skb->data;
3417 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003418
3419 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3420
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003421 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003422 case HCI_EV_INQUIRY_COMPLETE:
3423 hci_inquiry_complete_evt(hdev, skb);
3424 break;
3425
3426 case HCI_EV_INQUIRY_RESULT:
3427 hci_inquiry_result_evt(hdev, skb);
3428 break;
3429
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003430 case HCI_EV_CONN_COMPLETE:
3431 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003432 break;
3433
Linus Torvalds1da177e2005-04-16 15:20:36 -07003434 case HCI_EV_CONN_REQUEST:
3435 hci_conn_request_evt(hdev, skb);
3436 break;
3437
Linus Torvalds1da177e2005-04-16 15:20:36 -07003438 case HCI_EV_DISCONN_COMPLETE:
3439 hci_disconn_complete_evt(hdev, skb);
3440 break;
3441
Linus Torvalds1da177e2005-04-16 15:20:36 -07003442 case HCI_EV_AUTH_COMPLETE:
3443 hci_auth_complete_evt(hdev, skb);
3444 break;
3445
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003446 case HCI_EV_REMOTE_NAME:
3447 hci_remote_name_evt(hdev, skb);
3448 break;
3449
Linus Torvalds1da177e2005-04-16 15:20:36 -07003450 case HCI_EV_ENCRYPT_CHANGE:
3451 hci_encrypt_change_evt(hdev, skb);
3452 break;
3453
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003454 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3455 hci_change_link_key_complete_evt(hdev, skb);
3456 break;
3457
3458 case HCI_EV_REMOTE_FEATURES:
3459 hci_remote_features_evt(hdev, skb);
3460 break;
3461
3462 case HCI_EV_REMOTE_VERSION:
3463 hci_remote_version_evt(hdev, skb);
3464 break;
3465
3466 case HCI_EV_QOS_SETUP_COMPLETE:
3467 hci_qos_setup_complete_evt(hdev, skb);
3468 break;
3469
3470 case HCI_EV_CMD_COMPLETE:
3471 hci_cmd_complete_evt(hdev, skb);
3472 break;
3473
3474 case HCI_EV_CMD_STATUS:
3475 hci_cmd_status_evt(hdev, skb);
3476 break;
3477
3478 case HCI_EV_ROLE_CHANGE:
3479 hci_role_change_evt(hdev, skb);
3480 break;
3481
3482 case HCI_EV_NUM_COMP_PKTS:
3483 hci_num_comp_pkts_evt(hdev, skb);
3484 break;
3485
3486 case HCI_EV_MODE_CHANGE:
3487 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003488 break;
3489
3490 case HCI_EV_PIN_CODE_REQ:
3491 hci_pin_code_request_evt(hdev, skb);
3492 break;
3493
3494 case HCI_EV_LINK_KEY_REQ:
3495 hci_link_key_request_evt(hdev, skb);
3496 break;
3497
3498 case HCI_EV_LINK_KEY_NOTIFY:
3499 hci_link_key_notify_evt(hdev, skb);
3500 break;
3501
3502 case HCI_EV_CLOCK_OFFSET:
3503 hci_clock_offset_evt(hdev, skb);
3504 break;
3505
Marcel Holtmanna8746412008-07-14 20:13:46 +02003506 case HCI_EV_PKT_TYPE_CHANGE:
3507 hci_pkt_type_change_evt(hdev, skb);
3508 break;
3509
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003510 case HCI_EV_PSCAN_REP_MODE:
3511 hci_pscan_rep_mode_evt(hdev, skb);
3512 break;
3513
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003514 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3515 hci_inquiry_result_with_rssi_evt(hdev, skb);
3516 break;
3517
3518 case HCI_EV_REMOTE_EXT_FEATURES:
3519 hci_remote_ext_features_evt(hdev, skb);
3520 break;
3521
3522 case HCI_EV_SYNC_CONN_COMPLETE:
3523 hci_sync_conn_complete_evt(hdev, skb);
3524 break;
3525
3526 case HCI_EV_SYNC_CONN_CHANGED:
3527 hci_sync_conn_changed_evt(hdev, skb);
3528 break;
3529
Marcel Holtmann04837f62006-07-03 10:02:33 +02003530 case HCI_EV_SNIFF_SUBRATE:
3531 hci_sniff_subrate_evt(hdev, skb);
3532 break;
3533
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003534 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3535 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003536 break;
3537
Marcel Holtmann04936842008-07-14 20:13:48 +02003538 case HCI_EV_IO_CAPA_REQUEST:
3539 hci_io_capa_request_evt(hdev, skb);
3540 break;
3541
Johan Hedberg03b555e2011-01-04 15:40:05 +02003542 case HCI_EV_IO_CAPA_REPLY:
3543 hci_io_capa_reply_evt(hdev, skb);
3544 break;
3545
Johan Hedberga5c29682011-02-19 12:05:57 -03003546 case HCI_EV_USER_CONFIRM_REQUEST:
3547 hci_user_confirm_request_evt(hdev, skb);
3548 break;
3549
Brian Gix1143d452011-11-23 08:28:34 -08003550 case HCI_EV_USER_PASSKEY_REQUEST:
3551 hci_user_passkey_request_evt(hdev, skb);
3552 break;
3553
Marcel Holtmann04936842008-07-14 20:13:48 +02003554 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3555 hci_simple_pair_complete_evt(hdev, skb);
3556 break;
3557
Marcel Holtmann41a96212008-07-14 20:13:48 +02003558 case HCI_EV_REMOTE_HOST_FEATURES:
3559 hci_remote_host_features_evt(hdev, skb);
3560 break;
3561
Ville Tervofcd89c02011-02-10 22:38:47 -03003562 case HCI_EV_LE_META:
3563 hci_le_meta_evt(hdev, skb);
3564 break;
3565
Szymon Janc2763eda2011-03-22 13:12:22 +01003566 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3567 hci_remote_oob_data_request_evt(hdev, skb);
3568 break;
3569
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003570 case HCI_EV_NUM_COMP_BLOCKS:
3571 hci_num_comp_blocks_evt(hdev, skb);
3572 break;
3573
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003574 default:
3575 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003576 break;
3577 }
3578
3579 kfree_skb(skb);
3580 hdev->stat.evt_rx++;
3581}