blob: ef45e10c44f29e5dbc787069669e2ca9592ee232 [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);
Ram Malovany4a20bce2012-07-19 10:26:11 +03001403 } else {
1404 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001405 }
1406
Johan Hedbergb644ba32012-01-17 21:48:47 +02001407 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001408 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001409
1410discov_complete:
1411 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1412}
1413
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001414static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1415{
Johan Hedberg127178d2010-11-18 22:22:29 +02001416 struct hci_cp_remote_name_req *cp;
1417 struct hci_conn *conn;
1418
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001419 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001420
1421 /* If successful wait for the name req complete event before
1422 * checking for the need to do authentication */
1423 if (!status)
1424 return;
1425
1426 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1427 if (!cp)
1428 return;
1429
1430 hci_dev_lock(hdev);
1431
1432 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001433
1434 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1435 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1436
Johan Hedberg79c6c702011-04-28 11:28:55 -07001437 if (!conn)
1438 goto unlock;
1439
1440 if (!hci_outgoing_auth_needed(hdev, conn))
1441 goto unlock;
1442
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001443 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001444 struct hci_cp_auth_requested cp;
1445 cp.handle = __cpu_to_le16(conn->handle);
1446 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1447 }
1448
Johan Hedberg79c6c702011-04-28 11:28:55 -07001449unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001450 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001451}
1452
Marcel Holtmann769be972008-07-14 20:13:49 +02001453static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1454{
1455 struct hci_cp_read_remote_features *cp;
1456 struct hci_conn *conn;
1457
1458 BT_DBG("%s status 0x%x", hdev->name, status);
1459
1460 if (!status)
1461 return;
1462
1463 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1464 if (!cp)
1465 return;
1466
1467 hci_dev_lock(hdev);
1468
1469 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1470 if (conn) {
1471 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001472 hci_proto_connect_cfm(conn, status);
1473 hci_conn_put(conn);
1474 }
1475 }
1476
1477 hci_dev_unlock(hdev);
1478}
1479
1480static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1481{
1482 struct hci_cp_read_remote_ext_features *cp;
1483 struct hci_conn *conn;
1484
1485 BT_DBG("%s status 0x%x", hdev->name, status);
1486
1487 if (!status)
1488 return;
1489
1490 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1491 if (!cp)
1492 return;
1493
1494 hci_dev_lock(hdev);
1495
1496 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1497 if (conn) {
1498 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001499 hci_proto_connect_cfm(conn, status);
1500 hci_conn_put(conn);
1501 }
1502 }
1503
1504 hci_dev_unlock(hdev);
1505}
1506
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001507static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1508{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001509 struct hci_cp_setup_sync_conn *cp;
1510 struct hci_conn *acl, *sco;
1511 __u16 handle;
1512
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001513 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001514
1515 if (!status)
1516 return;
1517
1518 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1519 if (!cp)
1520 return;
1521
1522 handle = __le16_to_cpu(cp->handle);
1523
1524 BT_DBG("%s handle %d", hdev->name, handle);
1525
1526 hci_dev_lock(hdev);
1527
1528 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001529 if (acl) {
1530 sco = acl->link;
1531 if (sco) {
1532 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001533
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001534 hci_proto_connect_cfm(sco, status);
1535 hci_conn_del(sco);
1536 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001537 }
1538
1539 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001540}
1541
1542static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1543{
1544 struct hci_cp_sniff_mode *cp;
1545 struct hci_conn *conn;
1546
1547 BT_DBG("%s status 0x%x", hdev->name, status);
1548
1549 if (!status)
1550 return;
1551
1552 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1553 if (!cp)
1554 return;
1555
1556 hci_dev_lock(hdev);
1557
1558 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001559 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001560 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001561
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001562 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001563 hci_sco_setup(conn, status);
1564 }
1565
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001566 hci_dev_unlock(hdev);
1567}
1568
1569static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1570{
1571 struct hci_cp_exit_sniff_mode *cp;
1572 struct hci_conn *conn;
1573
1574 BT_DBG("%s status 0x%x", hdev->name, status);
1575
1576 if (!status)
1577 return;
1578
1579 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1580 if (!cp)
1581 return;
1582
1583 hci_dev_lock(hdev);
1584
1585 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001586 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001587 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001588
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001589 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001590 hci_sco_setup(conn, status);
1591 }
1592
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001593 hci_dev_unlock(hdev);
1594}
1595
Johan Hedberg88c3df12012-02-09 14:27:38 +02001596static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1597{
1598 struct hci_cp_disconnect *cp;
1599 struct hci_conn *conn;
1600
1601 if (!status)
1602 return;
1603
1604 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1605 if (!cp)
1606 return;
1607
1608 hci_dev_lock(hdev);
1609
1610 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1611 if (conn)
1612 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001613 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001614
1615 hci_dev_unlock(hdev);
1616}
1617
Ville Tervofcd89c02011-02-10 22:38:47 -03001618static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1619{
1620 struct hci_cp_le_create_conn *cp;
1621 struct hci_conn *conn;
1622
1623 BT_DBG("%s status 0x%x", hdev->name, status);
1624
1625 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1626 if (!cp)
1627 return;
1628
1629 hci_dev_lock(hdev);
1630
1631 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1632
1633 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1634 conn);
1635
1636 if (status) {
1637 if (conn && conn->state == BT_CONNECT) {
1638 conn->state = BT_CLOSED;
1639 hci_proto_connect_cfm(conn, status);
1640 hci_conn_del(conn);
1641 }
1642 } else {
1643 if (!conn) {
1644 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001645 if (conn) {
1646 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001647 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001648 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001649 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001650 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001651 }
1652 }
1653
1654 hci_dev_unlock(hdev);
1655}
1656
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001657static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1658{
1659 BT_DBG("%s status 0x%x", hdev->name, status);
1660}
1661
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001662static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1663{
1664 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001665 struct discovery_state *discov = &hdev->discovery;
1666 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001667
1668 BT_DBG("%s status %d", hdev->name, status);
1669
Johan Hedberg23bb5762010-12-21 23:01:27 +02001670 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001671
1672 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001673
1674 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1675 return;
1676
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001677 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001678 return;
1679
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001680 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001681
Andre Guedes343f9352012-02-17 20:39:37 -03001682 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001683 goto unlock;
1684
1685 if (list_empty(&discov->resolve)) {
1686 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1687 goto unlock;
1688 }
1689
1690 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1691 if (e && hci_resolve_name(hdev, e) == 0) {
1692 e->name_state = NAME_PENDING;
1693 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1694 } else {
1695 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1696 }
1697
1698unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001699 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001700}
1701
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1703{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001704 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001705 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 int num_rsp = *((__u8 *) skb->data);
1707
1708 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1709
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001710 if (!num_rsp)
1711 return;
1712
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001714
Johan Hedberge17acd42011-03-30 23:57:16 +03001715 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001716 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001717
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 bacpy(&data.bdaddr, &info->bdaddr);
1719 data.pscan_rep_mode = info->pscan_rep_mode;
1720 data.pscan_period_mode = info->pscan_period_mode;
1721 data.pscan_mode = info->pscan_mode;
1722 memcpy(data.dev_class, info->dev_class, 3);
1723 data.clock_offset = info->clock_offset;
1724 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001725 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001726
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001727 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001728 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001729 info->dev_class, 0, !name_known, ssp, NULL,
1730 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001732
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 hci_dev_unlock(hdev);
1734}
1735
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001736static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001738 struct hci_ev_conn_complete *ev = (void *) skb->data;
1739 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001741 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001742
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001744
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001745 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001746 if (!conn) {
1747 if (ev->link_type != SCO_LINK)
1748 goto unlock;
1749
1750 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1751 if (!conn)
1752 goto unlock;
1753
1754 conn->type = SCO_LINK;
1755 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001756
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001757 if (!ev->status) {
1758 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001759
1760 if (conn->type == ACL_LINK) {
1761 conn->state = BT_CONFIG;
1762 hci_conn_hold(conn);
Szymon Janc3cf3cfc2012-07-19 14:46:08 +02001763
1764 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1765 !hci_find_link_key(hdev, &ev->bdaddr))
1766 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1767 else
1768 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001769 } else
1770 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001771
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001772 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001773 hci_conn_add_sysfs(conn);
1774
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001775 if (test_bit(HCI_AUTH, &hdev->flags))
1776 conn->link_mode |= HCI_LM_AUTH;
1777
1778 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1779 conn->link_mode |= HCI_LM_ENCRYPT;
1780
1781 /* Get remote features */
1782 if (conn->type == ACL_LINK) {
1783 struct hci_cp_read_remote_features cp;
1784 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001785 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001786 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001787 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001788
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001789 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001790 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001791 struct hci_cp_change_conn_ptype cp;
1792 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001793 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001794 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1795 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001796 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001797 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001798 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001799 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001800 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001801 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001802 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001803
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001804 if (conn->type == ACL_LINK)
1805 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001806
Marcel Holtmann769be972008-07-14 20:13:49 +02001807 if (ev->status) {
1808 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001809 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001810 } else if (ev->link_type != ACL_LINK)
1811 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001812
1813unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001815
1816 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817}
1818
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1820{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001821 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 int mask = hdev->link_mode;
1823
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001824 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1825 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
1827 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1828
Szymon Janc138d22e2011-02-17 16:44:23 +01001829 if ((mask & HCI_LM_ACCEPT) &&
1830 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001832 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834
1835 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001836
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001837 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1838 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001839 memcpy(ie->data.dev_class, ev->dev_class, 3);
1840
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1842 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001843 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1844 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001845 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 hci_dev_unlock(hdev);
1847 return;
1848 }
1849 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001850
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 memcpy(conn->dev_class, ev->dev_class, 3);
1852 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001853
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854 hci_dev_unlock(hdev);
1855
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001856 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1857 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001859 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001861 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1862 cp.role = 0x00; /* Become master */
1863 else
1864 cp.role = 0x01; /* Remain slave */
1865
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001866 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1867 &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001868 } else {
1869 struct hci_cp_accept_sync_conn_req cp;
1870
1871 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001872 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001873
1874 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1875 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1876 cp.max_latency = cpu_to_le16(0xffff);
1877 cp.content_format = cpu_to_le16(hdev->voice_setting);
1878 cp.retrans_effort = 0xff;
1879
1880 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001881 sizeof(cp), &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001882 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883 } else {
1884 /* Connection rejected */
1885 struct hci_cp_reject_conn_req cp;
1886
1887 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001888 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001889 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 }
1891}
1892
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1894{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001895 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001896 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897
1898 BT_DBG("%s status %d", hdev->name, ev->status);
1899
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900 hci_dev_lock(hdev);
1901
Marcel Holtmann04837f62006-07-03 10:02:33 +02001902 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001903 if (!conn)
1904 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001905
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001906 if (ev->status == 0)
1907 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908
Johan Hedbergb644ba32012-01-17 21:48:47 +02001909 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1910 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001911 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001912 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1913 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001914 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001915 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001916 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001917 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001918
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001919 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301920 if (conn->type == ACL_LINK && conn->flush_key)
1921 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001922 hci_proto_disconn_cfm(conn, ev->reason);
1923 hci_conn_del(conn);
1924 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001925
1926unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927 hci_dev_unlock(hdev);
1928}
1929
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001930static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1931{
1932 struct hci_ev_auth_complete *ev = (void *) skb->data;
1933 struct hci_conn *conn;
1934
1935 BT_DBG("%s status %d", hdev->name, ev->status);
1936
1937 hci_dev_lock(hdev);
1938
1939 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001940 if (!conn)
1941 goto unlock;
1942
1943 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001944 if (!hci_conn_ssp_enabled(conn) &&
1945 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001946 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001947 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001948 conn->link_mode |= HCI_LM_AUTH;
1949 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001950 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001951 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001952 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001953 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001954 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001955
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001956 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1957 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001958
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001959 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001960 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001961 struct hci_cp_set_conn_encrypt cp;
1962 cp.handle = ev->handle;
1963 cp.encrypt = 0x01;
1964 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1965 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001966 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001967 conn->state = BT_CONNECTED;
1968 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001969 hci_conn_put(conn);
1970 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001971 } else {
1972 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001973
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001974 hci_conn_hold(conn);
1975 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1976 hci_conn_put(conn);
1977 }
1978
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001979 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001980 if (!ev->status) {
1981 struct hci_cp_set_conn_encrypt cp;
1982 cp.handle = ev->handle;
1983 cp.encrypt = 0x01;
1984 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1985 &cp);
1986 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001987 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001988 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001989 }
1990 }
1991
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001992unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001993 hci_dev_unlock(hdev);
1994}
1995
1996static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1997{
Johan Hedberg127178d2010-11-18 22:22:29 +02001998 struct hci_ev_remote_name *ev = (void *) skb->data;
1999 struct hci_conn *conn;
2000
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002001 BT_DBG("%s", hdev->name);
2002
2003 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002004
2005 hci_dev_lock(hdev);
2006
2007 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002008
2009 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2010 goto check_auth;
2011
2012 if (ev->status == 0)
2013 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002014 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002015 else
2016 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2017
2018check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002019 if (!conn)
2020 goto unlock;
2021
2022 if (!hci_outgoing_auth_needed(hdev, conn))
2023 goto unlock;
2024
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002025 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002026 struct hci_cp_auth_requested cp;
2027 cp.handle = __cpu_to_le16(conn->handle);
2028 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2029 }
2030
Johan Hedberg79c6c702011-04-28 11:28:55 -07002031unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002032 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002033}
2034
2035static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2036{
2037 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2038 struct hci_conn *conn;
2039
2040 BT_DBG("%s status %d", hdev->name, ev->status);
2041
2042 hci_dev_lock(hdev);
2043
2044 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2045 if (conn) {
2046 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002047 if (ev->encrypt) {
2048 /* Encryption implies authentication */
2049 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002050 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002051 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002052 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002053 conn->link_mode &= ~HCI_LM_ENCRYPT;
2054 }
2055
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002056 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002057
Gustavo Padovana7d77232012-05-13 03:20:07 -03002058 if (ev->status && conn->state == BT_CONNECTED) {
2059 hci_acl_disconn(conn, 0x13);
2060 hci_conn_put(conn);
2061 goto unlock;
2062 }
2063
Marcel Holtmannf8558552008-07-14 20:13:49 +02002064 if (conn->state == BT_CONFIG) {
2065 if (!ev->status)
2066 conn->state = BT_CONNECTED;
2067
2068 hci_proto_connect_cfm(conn, ev->status);
2069 hci_conn_put(conn);
2070 } else
2071 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002072 }
2073
Gustavo Padovana7d77232012-05-13 03:20:07 -03002074unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002075 hci_dev_unlock(hdev);
2076}
2077
2078static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2079{
2080 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2081 struct hci_conn *conn;
2082
2083 BT_DBG("%s status %d", hdev->name, ev->status);
2084
2085 hci_dev_lock(hdev);
2086
2087 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2088 if (conn) {
2089 if (!ev->status)
2090 conn->link_mode |= HCI_LM_SECURE;
2091
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002092 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002093
2094 hci_key_change_cfm(conn, ev->status);
2095 }
2096
2097 hci_dev_unlock(hdev);
2098}
2099
2100static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2101{
2102 struct hci_ev_remote_features *ev = (void *) skb->data;
2103 struct hci_conn *conn;
2104
2105 BT_DBG("%s status %d", hdev->name, ev->status);
2106
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002107 hci_dev_lock(hdev);
2108
2109 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002110 if (!conn)
2111 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002112
Johan Hedbergccd556f2010-11-10 17:11:51 +02002113 if (!ev->status)
2114 memcpy(conn->features, ev->features, 8);
2115
2116 if (conn->state != BT_CONFIG)
2117 goto unlock;
2118
2119 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2120 struct hci_cp_read_remote_ext_features cp;
2121 cp.handle = ev->handle;
2122 cp.page = 0x01;
2123 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002124 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002125 goto unlock;
2126 }
2127
Johan Hedberg671267b2012-05-12 16:11:50 -03002128 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002129 struct hci_cp_remote_name_req cp;
2130 memset(&cp, 0, sizeof(cp));
2131 bacpy(&cp.bdaddr, &conn->dst);
2132 cp.pscan_rep_mode = 0x02;
2133 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002134 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2135 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002136 conn->dst_type, 0, NULL, 0,
2137 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002138
Johan Hedberg127178d2010-11-18 22:22:29 +02002139 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002140 conn->state = BT_CONNECTED;
2141 hci_proto_connect_cfm(conn, ev->status);
2142 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002143 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002144
Johan Hedbergccd556f2010-11-10 17:11:51 +02002145unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002146 hci_dev_unlock(hdev);
2147}
2148
2149static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2150{
2151 BT_DBG("%s", hdev->name);
2152}
2153
2154static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2155{
2156 BT_DBG("%s", hdev->name);
2157}
2158
2159static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2160{
2161 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2162 __u16 opcode;
2163
2164 skb_pull(skb, sizeof(*ev));
2165
2166 opcode = __le16_to_cpu(ev->opcode);
2167
2168 switch (opcode) {
2169 case HCI_OP_INQUIRY_CANCEL:
2170 hci_cc_inquiry_cancel(hdev, skb);
2171 break;
2172
2173 case HCI_OP_EXIT_PERIODIC_INQ:
2174 hci_cc_exit_periodic_inq(hdev, skb);
2175 break;
2176
2177 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2178 hci_cc_remote_name_req_cancel(hdev, skb);
2179 break;
2180
2181 case HCI_OP_ROLE_DISCOVERY:
2182 hci_cc_role_discovery(hdev, skb);
2183 break;
2184
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002185 case HCI_OP_READ_LINK_POLICY:
2186 hci_cc_read_link_policy(hdev, skb);
2187 break;
2188
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002189 case HCI_OP_WRITE_LINK_POLICY:
2190 hci_cc_write_link_policy(hdev, skb);
2191 break;
2192
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002193 case HCI_OP_READ_DEF_LINK_POLICY:
2194 hci_cc_read_def_link_policy(hdev, skb);
2195 break;
2196
2197 case HCI_OP_WRITE_DEF_LINK_POLICY:
2198 hci_cc_write_def_link_policy(hdev, skb);
2199 break;
2200
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002201 case HCI_OP_RESET:
2202 hci_cc_reset(hdev, skb);
2203 break;
2204
2205 case HCI_OP_WRITE_LOCAL_NAME:
2206 hci_cc_write_local_name(hdev, skb);
2207 break;
2208
2209 case HCI_OP_READ_LOCAL_NAME:
2210 hci_cc_read_local_name(hdev, skb);
2211 break;
2212
2213 case HCI_OP_WRITE_AUTH_ENABLE:
2214 hci_cc_write_auth_enable(hdev, skb);
2215 break;
2216
2217 case HCI_OP_WRITE_ENCRYPT_MODE:
2218 hci_cc_write_encrypt_mode(hdev, skb);
2219 break;
2220
2221 case HCI_OP_WRITE_SCAN_ENABLE:
2222 hci_cc_write_scan_enable(hdev, skb);
2223 break;
2224
2225 case HCI_OP_READ_CLASS_OF_DEV:
2226 hci_cc_read_class_of_dev(hdev, skb);
2227 break;
2228
2229 case HCI_OP_WRITE_CLASS_OF_DEV:
2230 hci_cc_write_class_of_dev(hdev, skb);
2231 break;
2232
2233 case HCI_OP_READ_VOICE_SETTING:
2234 hci_cc_read_voice_setting(hdev, skb);
2235 break;
2236
2237 case HCI_OP_WRITE_VOICE_SETTING:
2238 hci_cc_write_voice_setting(hdev, skb);
2239 break;
2240
2241 case HCI_OP_HOST_BUFFER_SIZE:
2242 hci_cc_host_buffer_size(hdev, skb);
2243 break;
2244
Marcel Holtmann333140b2008-07-14 20:13:48 +02002245 case HCI_OP_WRITE_SSP_MODE:
2246 hci_cc_write_ssp_mode(hdev, skb);
2247 break;
2248
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002249 case HCI_OP_READ_LOCAL_VERSION:
2250 hci_cc_read_local_version(hdev, skb);
2251 break;
2252
2253 case HCI_OP_READ_LOCAL_COMMANDS:
2254 hci_cc_read_local_commands(hdev, skb);
2255 break;
2256
2257 case HCI_OP_READ_LOCAL_FEATURES:
2258 hci_cc_read_local_features(hdev, skb);
2259 break;
2260
Andre Guedes971e3a42011-06-30 19:20:52 -03002261 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2262 hci_cc_read_local_ext_features(hdev, skb);
2263 break;
2264
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002265 case HCI_OP_READ_BUFFER_SIZE:
2266 hci_cc_read_buffer_size(hdev, skb);
2267 break;
2268
2269 case HCI_OP_READ_BD_ADDR:
2270 hci_cc_read_bd_addr(hdev, skb);
2271 break;
2272
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002273 case HCI_OP_READ_DATA_BLOCK_SIZE:
2274 hci_cc_read_data_block_size(hdev, skb);
2275 break;
2276
Johan Hedberg23bb5762010-12-21 23:01:27 +02002277 case HCI_OP_WRITE_CA_TIMEOUT:
2278 hci_cc_write_ca_timeout(hdev, skb);
2279 break;
2280
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002281 case HCI_OP_READ_FLOW_CONTROL_MODE:
2282 hci_cc_read_flow_control_mode(hdev, skb);
2283 break;
2284
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002285 case HCI_OP_READ_LOCAL_AMP_INFO:
2286 hci_cc_read_local_amp_info(hdev, skb);
2287 break;
2288
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002289 case HCI_OP_DELETE_STORED_LINK_KEY:
2290 hci_cc_delete_stored_link_key(hdev, skb);
2291 break;
2292
Johan Hedbergd5859e22011-01-25 01:19:58 +02002293 case HCI_OP_SET_EVENT_MASK:
2294 hci_cc_set_event_mask(hdev, skb);
2295 break;
2296
2297 case HCI_OP_WRITE_INQUIRY_MODE:
2298 hci_cc_write_inquiry_mode(hdev, skb);
2299 break;
2300
2301 case HCI_OP_READ_INQ_RSP_TX_POWER:
2302 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2303 break;
2304
2305 case HCI_OP_SET_EVENT_FLT:
2306 hci_cc_set_event_flt(hdev, skb);
2307 break;
2308
Johan Hedberg980e1a52011-01-22 06:10:07 +02002309 case HCI_OP_PIN_CODE_REPLY:
2310 hci_cc_pin_code_reply(hdev, skb);
2311 break;
2312
2313 case HCI_OP_PIN_CODE_NEG_REPLY:
2314 hci_cc_pin_code_neg_reply(hdev, skb);
2315 break;
2316
Szymon Jancc35938b2011-03-22 13:12:21 +01002317 case HCI_OP_READ_LOCAL_OOB_DATA:
2318 hci_cc_read_local_oob_data_reply(hdev, skb);
2319 break;
2320
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002321 case HCI_OP_LE_READ_BUFFER_SIZE:
2322 hci_cc_le_read_buffer_size(hdev, skb);
2323 break;
2324
Johan Hedberga5c29682011-02-19 12:05:57 -03002325 case HCI_OP_USER_CONFIRM_REPLY:
2326 hci_cc_user_confirm_reply(hdev, skb);
2327 break;
2328
2329 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2330 hci_cc_user_confirm_neg_reply(hdev, skb);
2331 break;
2332
Brian Gix1143d452011-11-23 08:28:34 -08002333 case HCI_OP_USER_PASSKEY_REPLY:
2334 hci_cc_user_passkey_reply(hdev, skb);
2335 break;
2336
2337 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2338 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002339 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002340
2341 case HCI_OP_LE_SET_SCAN_PARAM:
2342 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002343 break;
2344
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002345 case HCI_OP_LE_SET_SCAN_ENABLE:
2346 hci_cc_le_set_scan_enable(hdev, skb);
2347 break;
2348
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002349 case HCI_OP_LE_LTK_REPLY:
2350 hci_cc_le_ltk_reply(hdev, skb);
2351 break;
2352
2353 case HCI_OP_LE_LTK_NEG_REPLY:
2354 hci_cc_le_ltk_neg_reply(hdev, skb);
2355 break;
2356
Andre Guedesf9b49302011-06-30 19:20:53 -03002357 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2358 hci_cc_write_le_host_supported(hdev, skb);
2359 break;
2360
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002361 default:
2362 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2363 break;
2364 }
2365
Ville Tervo6bd32322011-02-16 16:32:41 +02002366 if (ev->opcode != HCI_OP_NOP)
2367 del_timer(&hdev->cmd_timer);
2368
Szymon Jancdec3b6a2012-12-11 08:51:19 +01002369 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002370 atomic_set(&hdev->cmd_cnt, 1);
2371 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002372 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002373 }
2374}
2375
2376static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2377{
2378 struct hci_ev_cmd_status *ev = (void *) skb->data;
2379 __u16 opcode;
2380
2381 skb_pull(skb, sizeof(*ev));
2382
2383 opcode = __le16_to_cpu(ev->opcode);
2384
2385 switch (opcode) {
2386 case HCI_OP_INQUIRY:
2387 hci_cs_inquiry(hdev, ev->status);
2388 break;
2389
2390 case HCI_OP_CREATE_CONN:
2391 hci_cs_create_conn(hdev, ev->status);
2392 break;
2393
2394 case HCI_OP_ADD_SCO:
2395 hci_cs_add_sco(hdev, ev->status);
2396 break;
2397
Marcel Holtmannf8558552008-07-14 20:13:49 +02002398 case HCI_OP_AUTH_REQUESTED:
2399 hci_cs_auth_requested(hdev, ev->status);
2400 break;
2401
2402 case HCI_OP_SET_CONN_ENCRYPT:
2403 hci_cs_set_conn_encrypt(hdev, ev->status);
2404 break;
2405
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002406 case HCI_OP_REMOTE_NAME_REQ:
2407 hci_cs_remote_name_req(hdev, ev->status);
2408 break;
2409
Marcel Holtmann769be972008-07-14 20:13:49 +02002410 case HCI_OP_READ_REMOTE_FEATURES:
2411 hci_cs_read_remote_features(hdev, ev->status);
2412 break;
2413
2414 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2415 hci_cs_read_remote_ext_features(hdev, ev->status);
2416 break;
2417
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002418 case HCI_OP_SETUP_SYNC_CONN:
2419 hci_cs_setup_sync_conn(hdev, ev->status);
2420 break;
2421
2422 case HCI_OP_SNIFF_MODE:
2423 hci_cs_sniff_mode(hdev, ev->status);
2424 break;
2425
2426 case HCI_OP_EXIT_SNIFF_MODE:
2427 hci_cs_exit_sniff_mode(hdev, ev->status);
2428 break;
2429
Johan Hedberg8962ee72011-01-20 12:40:27 +02002430 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002431 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002432 break;
2433
Ville Tervofcd89c02011-02-10 22:38:47 -03002434 case HCI_OP_LE_CREATE_CONN:
2435 hci_cs_le_create_conn(hdev, ev->status);
2436 break;
2437
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002438 case HCI_OP_LE_START_ENC:
2439 hci_cs_le_start_enc(hdev, ev->status);
2440 break;
2441
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002442 default:
2443 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2444 break;
2445 }
2446
Ville Tervo6bd32322011-02-16 16:32:41 +02002447 if (ev->opcode != HCI_OP_NOP)
2448 del_timer(&hdev->cmd_timer);
2449
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002450 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002451 atomic_set(&hdev->cmd_cnt, 1);
2452 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002453 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002454 }
2455}
2456
2457static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2458{
2459 struct hci_ev_role_change *ev = (void *) skb->data;
2460 struct hci_conn *conn;
2461
2462 BT_DBG("%s status %d", hdev->name, ev->status);
2463
2464 hci_dev_lock(hdev);
2465
2466 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2467 if (conn) {
2468 if (!ev->status) {
2469 if (ev->role)
2470 conn->link_mode &= ~HCI_LM_MASTER;
2471 else
2472 conn->link_mode |= HCI_LM_MASTER;
2473 }
2474
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002475 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002476
2477 hci_role_switch_cfm(conn, ev->status, ev->role);
2478 }
2479
2480 hci_dev_unlock(hdev);
2481}
2482
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2484{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002485 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486 int i;
2487
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002488 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2489 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2490 return;
2491 }
2492
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002493 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2494 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002495 BT_DBG("%s bad parameters", hdev->name);
2496 return;
2497 }
2498
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002499 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2500
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002501 for (i = 0; i < ev->num_hndl; i++) {
2502 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503 struct hci_conn *conn;
2504 __u16 handle, count;
2505
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002506 handle = __le16_to_cpu(info->handle);
2507 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508
2509 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002510 if (!conn)
2511 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002512
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002513 conn->sent -= count;
2514
2515 switch (conn->type) {
2516 case ACL_LINK:
2517 hdev->acl_cnt += count;
2518 if (hdev->acl_cnt > hdev->acl_pkts)
2519 hdev->acl_cnt = hdev->acl_pkts;
2520 break;
2521
2522 case LE_LINK:
2523 if (hdev->le_pkts) {
2524 hdev->le_cnt += count;
2525 if (hdev->le_cnt > hdev->le_pkts)
2526 hdev->le_cnt = hdev->le_pkts;
2527 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002528 hdev->acl_cnt += count;
2529 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530 hdev->acl_cnt = hdev->acl_pkts;
2531 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002532 break;
2533
2534 case SCO_LINK:
2535 hdev->sco_cnt += count;
2536 if (hdev->sco_cnt > hdev->sco_pkts)
2537 hdev->sco_cnt = hdev->sco_pkts;
2538 break;
2539
2540 default:
2541 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2542 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543 }
2544 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002545
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002546 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002547}
2548
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002549static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002550 struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002551{
2552 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2553 int i;
2554
2555 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2556 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2557 return;
2558 }
2559
2560 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2561 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2562 BT_DBG("%s bad parameters", hdev->name);
2563 return;
2564 }
2565
2566 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2567 ev->num_hndl);
2568
2569 for (i = 0; i < ev->num_hndl; i++) {
2570 struct hci_comp_blocks_info *info = &ev->handles[i];
2571 struct hci_conn *conn;
2572 __u16 handle, block_count;
2573
2574 handle = __le16_to_cpu(info->handle);
2575 block_count = __le16_to_cpu(info->blocks);
2576
2577 conn = hci_conn_hash_lookup_handle(hdev, handle);
2578 if (!conn)
2579 continue;
2580
2581 conn->sent -= block_count;
2582
2583 switch (conn->type) {
2584 case ACL_LINK:
2585 hdev->block_cnt += block_count;
2586 if (hdev->block_cnt > hdev->num_blocks)
2587 hdev->block_cnt = hdev->num_blocks;
2588 break;
2589
2590 default:
2591 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2592 break;
2593 }
2594 }
2595
2596 queue_work(hdev->workqueue, &hdev->tx_work);
2597}
2598
Marcel Holtmann04837f62006-07-03 10:02:33 +02002599static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002601 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002602 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002603
2604 BT_DBG("%s status %d", hdev->name, ev->status);
2605
2606 hci_dev_lock(hdev);
2607
Marcel Holtmann04837f62006-07-03 10:02:33 +02002608 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2609 if (conn) {
2610 conn->mode = ev->mode;
2611 conn->interval = __le16_to_cpu(ev->interval);
2612
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002613 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002614 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002615 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002616 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002617 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002618 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002619
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002620 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002621 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002622 }
2623
2624 hci_dev_unlock(hdev);
2625}
2626
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2628{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002629 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2630 struct hci_conn *conn;
2631
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002632 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002633
2634 hci_dev_lock(hdev);
2635
2636 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002637 if (!conn)
2638 goto unlock;
2639
2640 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002641 hci_conn_hold(conn);
2642 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2643 hci_conn_put(conn);
2644 }
2645
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002646 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002647 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2648 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002649 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002650 u8 secure;
2651
2652 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2653 secure = 1;
2654 else
2655 secure = 0;
2656
Johan Hedberg744cf192011-11-08 20:40:14 +02002657 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002658 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002659
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002660unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002661 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662}
2663
Linus Torvalds1da177e2005-04-16 15:20:36 -07002664static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2665{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002666 struct hci_ev_link_key_req *ev = (void *) skb->data;
2667 struct hci_cp_link_key_reply cp;
2668 struct hci_conn *conn;
2669 struct link_key *key;
2670
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002671 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002672
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002673 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002674 return;
2675
2676 hci_dev_lock(hdev);
2677
2678 key = hci_find_link_key(hdev, &ev->bdaddr);
2679 if (!key) {
2680 BT_DBG("%s link key not found for %s", hdev->name,
2681 batostr(&ev->bdaddr));
2682 goto not_found;
2683 }
2684
2685 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2686 batostr(&ev->bdaddr));
2687
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002688 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002689 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002690 BT_DBG("%s ignoring debug key", hdev->name);
2691 goto not_found;
2692 }
2693
2694 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002695 if (conn) {
2696 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2697 conn->auth_type != 0xff &&
2698 (conn->auth_type & 0x01)) {
2699 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2700 goto not_found;
2701 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002702
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002703 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2704 conn->pending_sec_level == BT_SECURITY_HIGH) {
2705 BT_DBG("%s ignoring key unauthenticated for high \
2706 security", hdev->name);
2707 goto not_found;
2708 }
2709
2710 conn->key_type = key->type;
2711 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002712 }
2713
2714 bacpy(&cp.bdaddr, &ev->bdaddr);
2715 memcpy(cp.link_key, key->val, 16);
2716
2717 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2718
2719 hci_dev_unlock(hdev);
2720
2721 return;
2722
2723not_found:
2724 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2725 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002726}
2727
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2729{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002730 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2731 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002732 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002733
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002734 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002735
2736 hci_dev_lock(hdev);
2737
2738 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2739 if (conn) {
2740 hci_conn_hold(conn);
2741 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002742 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002743
2744 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2745 conn->key_type = ev->key_type;
2746
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002747 hci_conn_put(conn);
2748 }
2749
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002750 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002751 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002752 ev->key_type, pin_len);
2753
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002754 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002755}
2756
Marcel Holtmann04837f62006-07-03 10:02:33 +02002757static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2758{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002759 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002760 struct hci_conn *conn;
2761
2762 BT_DBG("%s status %d", hdev->name, ev->status);
2763
2764 hci_dev_lock(hdev);
2765
2766 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767 if (conn && !ev->status) {
2768 struct inquiry_entry *ie;
2769
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002770 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2771 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002772 ie->data.clock_offset = ev->clock_offset;
2773 ie->timestamp = jiffies;
2774 }
2775 }
2776
2777 hci_dev_unlock(hdev);
2778}
2779
Marcel Holtmanna8746412008-07-14 20:13:46 +02002780static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2781{
2782 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2783 struct hci_conn *conn;
2784
2785 BT_DBG("%s status %d", hdev->name, ev->status);
2786
2787 hci_dev_lock(hdev);
2788
2789 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2790 if (conn && !ev->status)
2791 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2792
2793 hci_dev_unlock(hdev);
2794}
2795
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002796static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2797{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002798 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002799 struct inquiry_entry *ie;
2800
2801 BT_DBG("%s", hdev->name);
2802
2803 hci_dev_lock(hdev);
2804
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002805 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2806 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002807 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2808 ie->timestamp = jiffies;
2809 }
2810
2811 hci_dev_unlock(hdev);
2812}
2813
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002814static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2815{
2816 struct inquiry_data data;
2817 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002818 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002819
2820 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2821
2822 if (!num_rsp)
2823 return;
2824
2825 hci_dev_lock(hdev);
2826
2827 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002828 struct inquiry_info_with_rssi_and_pscan_mode *info;
2829 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002830
Johan Hedberge17acd42011-03-30 23:57:16 +03002831 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002832 bacpy(&data.bdaddr, &info->bdaddr);
2833 data.pscan_rep_mode = info->pscan_rep_mode;
2834 data.pscan_period_mode = info->pscan_period_mode;
2835 data.pscan_mode = info->pscan_mode;
2836 memcpy(data.dev_class, info->dev_class, 3);
2837 data.clock_offset = info->clock_offset;
2838 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002839 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002840
2841 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002842 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002843 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002844 info->dev_class, info->rssi,
2845 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002846 }
2847 } else {
2848 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2849
Johan Hedberge17acd42011-03-30 23:57:16 +03002850 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002851 bacpy(&data.bdaddr, &info->bdaddr);
2852 data.pscan_rep_mode = info->pscan_rep_mode;
2853 data.pscan_period_mode = info->pscan_period_mode;
2854 data.pscan_mode = 0x00;
2855 memcpy(data.dev_class, info->dev_class, 3);
2856 data.clock_offset = info->clock_offset;
2857 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002858 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002859 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002860 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002861 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002862 info->dev_class, info->rssi,
2863 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002864 }
2865 }
2866
2867 hci_dev_unlock(hdev);
2868}
2869
2870static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2871{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002872 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2873 struct hci_conn *conn;
2874
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002875 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002876
Marcel Holtmann41a96212008-07-14 20:13:48 +02002877 hci_dev_lock(hdev);
2878
2879 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002880 if (!conn)
2881 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002882
Johan Hedbergccd556f2010-11-10 17:11:51 +02002883 if (!ev->status && ev->page == 0x01) {
2884 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002885
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002886 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2887 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002888 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002889
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002890 if (ev->features[0] & LMP_HOST_SSP)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002891 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002892 }
2893
Johan Hedbergccd556f2010-11-10 17:11:51 +02002894 if (conn->state != BT_CONFIG)
2895 goto unlock;
2896
Johan Hedberg671267b2012-05-12 16:11:50 -03002897 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002898 struct hci_cp_remote_name_req cp;
2899 memset(&cp, 0, sizeof(cp));
2900 bacpy(&cp.bdaddr, &conn->dst);
2901 cp.pscan_rep_mode = 0x02;
2902 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002903 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2904 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002905 conn->dst_type, 0, NULL, 0,
2906 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002907
Johan Hedberg127178d2010-11-18 22:22:29 +02002908 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002909 conn->state = BT_CONNECTED;
2910 hci_proto_connect_cfm(conn, ev->status);
2911 hci_conn_put(conn);
2912 }
2913
2914unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002915 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002916}
2917
2918static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2919{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002920 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2921 struct hci_conn *conn;
2922
2923 BT_DBG("%s status %d", hdev->name, ev->status);
2924
2925 hci_dev_lock(hdev);
2926
2927 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002928 if (!conn) {
2929 if (ev->link_type == ESCO_LINK)
2930 goto unlock;
2931
2932 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2933 if (!conn)
2934 goto unlock;
2935
2936 conn->type = SCO_LINK;
2937 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002938
Marcel Holtmann732547f2009-04-19 19:14:14 +02002939 switch (ev->status) {
2940 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002941 conn->handle = __le16_to_cpu(ev->handle);
2942 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002943
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002944 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002945 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002946 break;
2947
Stephen Coe705e5712010-02-16 11:29:44 -05002948 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002949 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002950 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002951 case 0x1f: /* Unspecified error */
2952 if (conn->out && conn->attempt < 2) {
2953 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2954 (hdev->esco_type & EDR_ESCO_MASK);
2955 hci_setup_sync(conn, conn->link->handle);
2956 goto unlock;
2957 }
2958 /* fall through */
2959
2960 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002961 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002962 break;
2963 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002964
2965 hci_proto_connect_cfm(conn, ev->status);
2966 if (ev->status)
2967 hci_conn_del(conn);
2968
2969unlock:
2970 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002971}
2972
2973static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2974{
2975 BT_DBG("%s", hdev->name);
2976}
2977
Marcel Holtmann04837f62006-07-03 10:02:33 +02002978static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2979{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002980 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002981
2982 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002983}
2984
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002985static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2986{
2987 struct inquiry_data data;
2988 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2989 int num_rsp = *((__u8 *) skb->data);
2990
2991 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2992
2993 if (!num_rsp)
2994 return;
2995
2996 hci_dev_lock(hdev);
2997
Johan Hedberge17acd42011-03-30 23:57:16 +03002998 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002999 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003000
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003001 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003002 data.pscan_rep_mode = info->pscan_rep_mode;
3003 data.pscan_period_mode = info->pscan_period_mode;
3004 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003005 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003006 data.clock_offset = info->clock_offset;
3007 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003008 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003009
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003010 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003011 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003012 sizeof(info->data),
3013 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003014 else
3015 name_known = true;
3016
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003017 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003018 &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003019 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003020 info->dev_class, info->rssi, !name_known,
3021 ssp, info->data, sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003022 }
3023
3024 hci_dev_unlock(hdev);
3025}
3026
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003027static inline u8 hci_get_auth_req(struct hci_conn *conn)
3028{
3029 /* If remote requests dedicated bonding follow that lead */
3030 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3031 /* If both remote and local IO capabilities allow MITM
3032 * protection then require it, otherwise don't */
3033 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3034 return 0x02;
3035 else
3036 return 0x03;
3037 }
3038
3039 /* If remote requests no-bonding follow that lead */
3040 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003041 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003042
3043 return conn->auth_type;
3044}
3045
Marcel Holtmann04936842008-07-14 20:13:48 +02003046static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3047{
3048 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3049 struct hci_conn *conn;
3050
3051 BT_DBG("%s", hdev->name);
3052
3053 hci_dev_lock(hdev);
3054
3055 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003056 if (!conn)
3057 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003058
Johan Hedberg03b555e2011-01-04 15:40:05 +02003059 hci_conn_hold(conn);
3060
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003061 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003062 goto unlock;
3063
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003064 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003065 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003066 struct hci_cp_io_capability_reply cp;
3067
3068 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303069 /* Change the IO capability from KeyboardDisplay
3070 * to DisplayYesNo as it is not supported by BT spec. */
3071 cp.capability = (conn->io_capability == 0x04) ?
3072 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003073 conn->auth_type = hci_get_auth_req(conn);
3074 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003075
Johan Hedberg58a681e2012-01-16 06:47:28 +02003076 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003077 hci_find_remote_oob_data(hdev, &conn->dst))
3078 cp.oob_data = 0x01;
3079 else
3080 cp.oob_data = 0x00;
3081
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003082 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3083 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003084 } else {
3085 struct hci_cp_io_capability_neg_reply cp;
3086
3087 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003088 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003089
3090 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3091 sizeof(cp), &cp);
3092 }
3093
3094unlock:
3095 hci_dev_unlock(hdev);
3096}
3097
3098static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3099{
3100 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3101 struct hci_conn *conn;
3102
3103 BT_DBG("%s", hdev->name);
3104
3105 hci_dev_lock(hdev);
3106
3107 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3108 if (!conn)
3109 goto unlock;
3110
Johan Hedberg03b555e2011-01-04 15:40:05 +02003111 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003112 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003113 if (ev->oob_data)
3114 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003115
3116unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003117 hci_dev_unlock(hdev);
3118}
3119
Johan Hedberga5c29682011-02-19 12:05:57 -03003120static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3121 struct sk_buff *skb)
3122{
3123 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003124 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003125 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003126
3127 BT_DBG("%s", hdev->name);
3128
3129 hci_dev_lock(hdev);
3130
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003131 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003132 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003133
Johan Hedberg7a828902011-04-28 11:28:53 -07003134 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3135 if (!conn)
3136 goto unlock;
3137
3138 loc_mitm = (conn->auth_type & 0x01);
3139 rem_mitm = (conn->remote_auth & 0x01);
3140
3141 /* If we require MITM but the remote device can't provide that
3142 * (it has NoInputNoOutput) then reject the confirmation
3143 * request. The only exception is when we're dedicated bonding
3144 * initiators (connect_cfm_cb set) since then we always have the MITM
3145 * bit set. */
3146 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3147 BT_DBG("Rejecting request: remote device can't provide MITM");
3148 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3149 sizeof(ev->bdaddr), &ev->bdaddr);
3150 goto unlock;
3151 }
3152
3153 /* If no side requires MITM protection; auto-accept */
3154 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3155 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003156
3157 /* If we're not the initiators request authorization to
3158 * proceed from user space (mgmt_user_confirm with
3159 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003160 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003161 BT_DBG("Confirming auto-accept as acceptor");
3162 confirm_hint = 1;
3163 goto confirm;
3164 }
3165
Johan Hedberg9f616562011-04-28 11:28:54 -07003166 BT_DBG("Auto-accept of user confirmation with %ums delay",
3167 hdev->auto_accept_delay);
3168
3169 if (hdev->auto_accept_delay > 0) {
3170 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3171 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3172 goto unlock;
3173 }
3174
Johan Hedberg7a828902011-04-28 11:28:53 -07003175 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3176 sizeof(ev->bdaddr), &ev->bdaddr);
3177 goto unlock;
3178 }
3179
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003180confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003181 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003182 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003183
3184unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003185 hci_dev_unlock(hdev);
3186}
3187
Brian Gix1143d452011-11-23 08:28:34 -08003188static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3189 struct sk_buff *skb)
3190{
3191 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3192
3193 BT_DBG("%s", hdev->name);
3194
3195 hci_dev_lock(hdev);
3196
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003197 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003198 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003199
3200 hci_dev_unlock(hdev);
3201}
3202
Marcel Holtmann04936842008-07-14 20:13:48 +02003203static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3204{
3205 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3206 struct hci_conn *conn;
3207
3208 BT_DBG("%s", hdev->name);
3209
3210 hci_dev_lock(hdev);
3211
3212 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003213 if (!conn)
3214 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003215
Johan Hedberg2a611692011-02-19 12:06:00 -03003216 /* To avoid duplicate auth_failed events to user space we check
3217 * the HCI_CONN_AUTH_PEND flag which will be set if we
3218 * initiated the authentication. A traditional auth_complete
3219 * event gets always produced as initiator and is also mapped to
3220 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003221 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003222 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003223 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003224
3225 hci_conn_put(conn);
3226
3227unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003228 hci_dev_unlock(hdev);
3229}
3230
Marcel Holtmann41a96212008-07-14 20:13:48 +02003231static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3232{
3233 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3234 struct inquiry_entry *ie;
3235
3236 BT_DBG("%s", hdev->name);
3237
3238 hci_dev_lock(hdev);
3239
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003240 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3241 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003242 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003243
3244 hci_dev_unlock(hdev);
3245}
3246
Szymon Janc2763eda2011-03-22 13:12:22 +01003247static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003248 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003249{
3250 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3251 struct oob_data *data;
3252
3253 BT_DBG("%s", hdev->name);
3254
3255 hci_dev_lock(hdev);
3256
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003257 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003258 goto unlock;
3259
Szymon Janc2763eda2011-03-22 13:12:22 +01003260 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3261 if (data) {
3262 struct hci_cp_remote_oob_data_reply cp;
3263
3264 bacpy(&cp.bdaddr, &ev->bdaddr);
3265 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3266 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3267
3268 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3269 &cp);
3270 } else {
3271 struct hci_cp_remote_oob_data_neg_reply cp;
3272
3273 bacpy(&cp.bdaddr, &ev->bdaddr);
3274 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3275 &cp);
3276 }
3277
Szymon Jance1ba1f12011-04-06 13:01:59 +02003278unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003279 hci_dev_unlock(hdev);
3280}
3281
Ville Tervofcd89c02011-02-10 22:38:47 -03003282static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3283{
3284 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3285 struct hci_conn *conn;
3286
3287 BT_DBG("%s status %d", hdev->name, ev->status);
3288
3289 hci_dev_lock(hdev);
3290
3291 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003292 if (!conn) {
3293 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3294 if (!conn) {
3295 BT_ERR("No memory for new connection");
3296 hci_dev_unlock(hdev);
3297 return;
3298 }
Andre Guedes29b79882011-05-31 14:20:54 -03003299
3300 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003301 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003302
3303 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003304 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3305 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003306 hci_proto_connect_cfm(conn, ev->status);
3307 conn->state = BT_CLOSED;
3308 hci_conn_del(conn);
3309 goto unlock;
3310 }
3311
Johan Hedbergb644ba32012-01-17 21:48:47 +02003312 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3313 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003314 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003315
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003316 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003317 conn->handle = __le16_to_cpu(ev->handle);
3318 conn->state = BT_CONNECTED;
3319
3320 hci_conn_hold_device(conn);
3321 hci_conn_add_sysfs(conn);
3322
3323 hci_proto_connect_cfm(conn, ev->status);
3324
3325unlock:
3326 hci_dev_unlock(hdev);
3327}
3328
Andre Guedes9aa04c92011-05-26 16:23:51 -03003329static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3330 struct sk_buff *skb)
3331{
Andre Guedese95beb42011-09-26 20:48:35 -03003332 u8 num_reports = skb->data[0];
3333 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003334 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003335
3336 hci_dev_lock(hdev);
3337
Andre Guedese95beb42011-09-26 20:48:35 -03003338 while (num_reports--) {
3339 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003340
Andre Guedes9aa04c92011-05-26 16:23:51 -03003341 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003342
Andre Guedes3c9e9192012-01-10 18:20:50 -03003343 rssi = ev->data[ev->length];
3344 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003345 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003346
Andre Guedese95beb42011-09-26 20:48:35 -03003347 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003348 }
3349
3350 hci_dev_unlock(hdev);
3351}
3352
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003353static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3354 struct sk_buff *skb)
3355{
3356 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3357 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003358 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003359 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003360 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003361
3362 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3363
3364 hci_dev_lock(hdev);
3365
3366 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003367 if (conn == NULL)
3368 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003369
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003370 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3371 if (ltk == NULL)
3372 goto not_found;
3373
3374 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003375 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003376
3377 if (ltk->authenticated)
3378 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003379
3380 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3381
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003382 if (ltk->type & HCI_SMP_STK) {
3383 list_del(&ltk->list);
3384 kfree(ltk);
3385 }
3386
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003387 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003388
3389 return;
3390
3391not_found:
3392 neg.handle = ev->handle;
3393 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3394 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003395}
3396
Ville Tervofcd89c02011-02-10 22:38:47 -03003397static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3398{
3399 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3400
3401 skb_pull(skb, sizeof(*le_ev));
3402
3403 switch (le_ev->subevent) {
3404 case HCI_EV_LE_CONN_COMPLETE:
3405 hci_le_conn_complete_evt(hdev, skb);
3406 break;
3407
Andre Guedes9aa04c92011-05-26 16:23:51 -03003408 case HCI_EV_LE_ADVERTISING_REPORT:
3409 hci_le_adv_report_evt(hdev, skb);
3410 break;
3411
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003412 case HCI_EV_LE_LTK_REQ:
3413 hci_le_ltk_request_evt(hdev, skb);
3414 break;
3415
Ville Tervofcd89c02011-02-10 22:38:47 -03003416 default:
3417 break;
3418 }
3419}
3420
Linus Torvalds1da177e2005-04-16 15:20:36 -07003421void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3422{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003423 struct hci_event_hdr *hdr = (void *) skb->data;
3424 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003425
3426 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3427
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003428 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003429 case HCI_EV_INQUIRY_COMPLETE:
3430 hci_inquiry_complete_evt(hdev, skb);
3431 break;
3432
3433 case HCI_EV_INQUIRY_RESULT:
3434 hci_inquiry_result_evt(hdev, skb);
3435 break;
3436
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003437 case HCI_EV_CONN_COMPLETE:
3438 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003439 break;
3440
Linus Torvalds1da177e2005-04-16 15:20:36 -07003441 case HCI_EV_CONN_REQUEST:
3442 hci_conn_request_evt(hdev, skb);
3443 break;
3444
Linus Torvalds1da177e2005-04-16 15:20:36 -07003445 case HCI_EV_DISCONN_COMPLETE:
3446 hci_disconn_complete_evt(hdev, skb);
3447 break;
3448
Linus Torvalds1da177e2005-04-16 15:20:36 -07003449 case HCI_EV_AUTH_COMPLETE:
3450 hci_auth_complete_evt(hdev, skb);
3451 break;
3452
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003453 case HCI_EV_REMOTE_NAME:
3454 hci_remote_name_evt(hdev, skb);
3455 break;
3456
Linus Torvalds1da177e2005-04-16 15:20:36 -07003457 case HCI_EV_ENCRYPT_CHANGE:
3458 hci_encrypt_change_evt(hdev, skb);
3459 break;
3460
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003461 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3462 hci_change_link_key_complete_evt(hdev, skb);
3463 break;
3464
3465 case HCI_EV_REMOTE_FEATURES:
3466 hci_remote_features_evt(hdev, skb);
3467 break;
3468
3469 case HCI_EV_REMOTE_VERSION:
3470 hci_remote_version_evt(hdev, skb);
3471 break;
3472
3473 case HCI_EV_QOS_SETUP_COMPLETE:
3474 hci_qos_setup_complete_evt(hdev, skb);
3475 break;
3476
3477 case HCI_EV_CMD_COMPLETE:
3478 hci_cmd_complete_evt(hdev, skb);
3479 break;
3480
3481 case HCI_EV_CMD_STATUS:
3482 hci_cmd_status_evt(hdev, skb);
3483 break;
3484
3485 case HCI_EV_ROLE_CHANGE:
3486 hci_role_change_evt(hdev, skb);
3487 break;
3488
3489 case HCI_EV_NUM_COMP_PKTS:
3490 hci_num_comp_pkts_evt(hdev, skb);
3491 break;
3492
3493 case HCI_EV_MODE_CHANGE:
3494 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003495 break;
3496
3497 case HCI_EV_PIN_CODE_REQ:
3498 hci_pin_code_request_evt(hdev, skb);
3499 break;
3500
3501 case HCI_EV_LINK_KEY_REQ:
3502 hci_link_key_request_evt(hdev, skb);
3503 break;
3504
3505 case HCI_EV_LINK_KEY_NOTIFY:
3506 hci_link_key_notify_evt(hdev, skb);
3507 break;
3508
3509 case HCI_EV_CLOCK_OFFSET:
3510 hci_clock_offset_evt(hdev, skb);
3511 break;
3512
Marcel Holtmanna8746412008-07-14 20:13:46 +02003513 case HCI_EV_PKT_TYPE_CHANGE:
3514 hci_pkt_type_change_evt(hdev, skb);
3515 break;
3516
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003517 case HCI_EV_PSCAN_REP_MODE:
3518 hci_pscan_rep_mode_evt(hdev, skb);
3519 break;
3520
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003521 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3522 hci_inquiry_result_with_rssi_evt(hdev, skb);
3523 break;
3524
3525 case HCI_EV_REMOTE_EXT_FEATURES:
3526 hci_remote_ext_features_evt(hdev, skb);
3527 break;
3528
3529 case HCI_EV_SYNC_CONN_COMPLETE:
3530 hci_sync_conn_complete_evt(hdev, skb);
3531 break;
3532
3533 case HCI_EV_SYNC_CONN_CHANGED:
3534 hci_sync_conn_changed_evt(hdev, skb);
3535 break;
3536
Marcel Holtmann04837f62006-07-03 10:02:33 +02003537 case HCI_EV_SNIFF_SUBRATE:
3538 hci_sniff_subrate_evt(hdev, skb);
3539 break;
3540
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003541 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3542 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003543 break;
3544
Marcel Holtmann04936842008-07-14 20:13:48 +02003545 case HCI_EV_IO_CAPA_REQUEST:
3546 hci_io_capa_request_evt(hdev, skb);
3547 break;
3548
Johan Hedberg03b555e2011-01-04 15:40:05 +02003549 case HCI_EV_IO_CAPA_REPLY:
3550 hci_io_capa_reply_evt(hdev, skb);
3551 break;
3552
Johan Hedberga5c29682011-02-19 12:05:57 -03003553 case HCI_EV_USER_CONFIRM_REQUEST:
3554 hci_user_confirm_request_evt(hdev, skb);
3555 break;
3556
Brian Gix1143d452011-11-23 08:28:34 -08003557 case HCI_EV_USER_PASSKEY_REQUEST:
3558 hci_user_passkey_request_evt(hdev, skb);
3559 break;
3560
Marcel Holtmann04936842008-07-14 20:13:48 +02003561 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3562 hci_simple_pair_complete_evt(hdev, skb);
3563 break;
3564
Marcel Holtmann41a96212008-07-14 20:13:48 +02003565 case HCI_EV_REMOTE_HOST_FEATURES:
3566 hci_remote_host_features_evt(hdev, skb);
3567 break;
3568
Ville Tervofcd89c02011-02-10 22:38:47 -03003569 case HCI_EV_LE_META:
3570 hci_le_meta_evt(hdev, skb);
3571 break;
3572
Szymon Janc2763eda2011-03-22 13:12:22 +01003573 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3574 hci_remote_oob_data_request_evt(hdev, skb);
3575 break;
3576
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003577 case HCI_EV_NUM_COMP_BLOCKS:
3578 hci_num_comp_blocks_evt(hdev, skb);
3579 break;
3580
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003581 default:
3582 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003583 break;
3584 }
3585
3586 kfree_skb(skb);
3587 hdev->stat.evt_rx++;
3588}