blob: 50ff9a9895314dfd346295327e0ae2f848db83e5 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <net/sock.h>
39
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020040#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <asm/unaligned.h>
42
43#include <net/bluetooth/bluetooth.h>
44#include <net/bluetooth/hci_core.h>
45
Linus Torvalds1da177e2005-04-16 15:20:36 -070046/* Handle HCI Event packets */
47
Marcel Holtmanna9de9242007-10-20 13:33:56 +020048static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070049{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020050 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
Andre Guedese6d465c2011-11-09 17:14:26 -030054 if (status) {
55 hci_dev_lock(hdev);
56 mgmt_stop_discovery_failed(hdev, status);
57 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020058 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030059 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
Andre Guedes89352e72011-11-04 14:16:53 -030061 clear_bit(HCI_INQUIRY, &hdev->flags);
62
Johan Hedberg56e5cb82011-11-08 20:40:16 +020063 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020064 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020065 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010066
Johan Hedberg23bb5762010-12-21 23:01:27 +020067 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010068
Marcel Holtmanna9de9242007-10-20 13:33:56 +020069 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070070}
71
Marcel Holtmanna9de9242007-10-20 13:33:56 +020072static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070073{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020074 __u8 status = *((__u8 *) skb->data);
75
76 BT_DBG("%s status 0x%x", hdev->name, status);
77
78 if (status)
79 return;
80
Marcel Holtmanna9de9242007-10-20 13:33:56 +020081 hci_conn_check_pending(hdev);
82}
83
84static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
85{
86 BT_DBG("%s", hdev->name);
87}
88
89static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
90{
91 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
Marcel Holtmanna9de9242007-10-20 13:33:56 +020094 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
Marcel Holtmanna9de9242007-10-20 13:33:56 +020096 if (rp->status)
97 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070098
Marcel Holtmanna9de9242007-10-20 13:33:56 +020099 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200101 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
102 if (conn) {
103 if (rp->role)
104 conn->link_mode &= ~HCI_LM_MASTER;
105 else
106 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200108
109 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110}
111
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200112static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
113{
114 struct hci_rp_read_link_policy *rp = (void *) skb->data;
115 struct hci_conn *conn;
116
117 BT_DBG("%s status 0x%x", hdev->name, rp->status);
118
119 if (rp->status)
120 return;
121
122 hci_dev_lock(hdev);
123
124 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
125 if (conn)
126 conn->link_policy = __le16_to_cpu(rp->policy);
127
128 hci_dev_unlock(hdev);
129}
130
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200131static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200133 struct hci_rp_write_link_policy *rp = (void *) skb->data;
134 struct hci_conn *conn;
135 void *sent;
136
137 BT_DBG("%s status 0x%x", hdev->name, rp->status);
138
139 if (rp->status)
140 return;
141
142 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
143 if (!sent)
144 return;
145
146 hci_dev_lock(hdev);
147
148 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200149 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700150 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200151
152 hci_dev_unlock(hdev);
153}
154
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200155static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
156{
157 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
158
159 BT_DBG("%s status 0x%x", hdev->name, rp->status);
160
161 if (rp->status)
162 return;
163
164 hdev->link_policy = __le16_to_cpu(rp->policy);
165}
166
167static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
168{
169 __u8 status = *((__u8 *) skb->data);
170 void *sent;
171
172 BT_DBG("%s status 0x%x", hdev->name, status);
173
174 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
175 if (!sent)
176 return;
177
178 if (!status)
179 hdev->link_policy = get_unaligned_le16(sent);
180
Johan Hedberg23bb5762010-12-21 23:01:27 +0200181 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200182}
183
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200184static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
185{
186 __u8 status = *((__u8 *) skb->data);
187
188 BT_DBG("%s status 0x%x", hdev->name, status);
189
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300190 clear_bit(HCI_RESET, &hdev->flags);
191
Johan Hedberg23bb5762010-12-21 23:01:27 +0200192 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300193
Johan Hedberga297e972012-02-21 17:55:47 +0200194 /* Reset all non-persistent flags */
Johan Hedberg9f8ce962012-03-02 03:06:04 +0200195 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN) | BIT(HCI_PENDING_CLASS));
Andre Guedes69775ff2012-02-23 16:50:05 +0200196
197 hdev->discovery.state = DISCOVERY_STOPPED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200198}
199
200static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
201{
202 __u8 status = *((__u8 *) skb->data);
203 void *sent;
204
205 BT_DBG("%s status 0x%x", hdev->name, status);
206
207 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
208 if (!sent)
209 return;
210
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200211 hci_dev_lock(hdev);
212
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200213 if (test_bit(HCI_MGMT, &hdev->dev_flags))
214 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200215 else if (!status)
216 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 hci_dev_unlock(hdev);
Johan Hedberg3159d382012-02-24 13:47:56 +0200219
220 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200221}
222
223static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
224{
225 struct hci_rp_read_local_name *rp = (void *) skb->data;
226
227 BT_DBG("%s status 0x%x", hdev->name, rp->status);
228
229 if (rp->status)
230 return;
231
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200232 if (test_bit(HCI_SETUP, &hdev->dev_flags))
233 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200234}
235
236static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
237{
238 __u8 status = *((__u8 *) skb->data);
239 void *sent;
240
241 BT_DBG("%s status 0x%x", hdev->name, status);
242
243 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
244 if (!sent)
245 return;
246
247 if (!status) {
248 __u8 param = *((__u8 *) sent);
249
250 if (param == AUTH_ENABLED)
251 set_bit(HCI_AUTH, &hdev->flags);
252 else
253 clear_bit(HCI_AUTH, &hdev->flags);
254 }
255
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200256 if (test_bit(HCI_MGMT, &hdev->dev_flags))
257 mgmt_auth_enable_complete(hdev, status);
258
Johan Hedberg23bb5762010-12-21 23:01:27 +0200259 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200260}
261
262static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
263{
264 __u8 status = *((__u8 *) skb->data);
265 void *sent;
266
267 BT_DBG("%s status 0x%x", hdev->name, status);
268
269 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
270 if (!sent)
271 return;
272
273 if (!status) {
274 __u8 param = *((__u8 *) sent);
275
276 if (param)
277 set_bit(HCI_ENCRYPT, &hdev->flags);
278 else
279 clear_bit(HCI_ENCRYPT, &hdev->flags);
280 }
281
Johan Hedberg23bb5762010-12-21 23:01:27 +0200282 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200283}
284
285static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
286{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200287 __u8 param, status = *((__u8 *) skb->data);
288 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200289 void *sent;
290
291 BT_DBG("%s status 0x%x", hdev->name, status);
292
293 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
294 if (!sent)
295 return;
296
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200297 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200298
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200299 hci_dev_lock(hdev);
300
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200301 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200302 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200303 hdev->discov_timeout = 0;
304 goto done;
305 }
306
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200307 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
308 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200309
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200310 if (param & SCAN_INQUIRY) {
311 set_bit(HCI_ISCAN, &hdev->flags);
312 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200313 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200314 if (hdev->discov_timeout > 0) {
315 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
316 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
317 to);
318 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200319 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200320 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200321
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200322 if (param & SCAN_PAGE) {
323 set_bit(HCI_PSCAN, &hdev->flags);
324 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200325 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200326 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200327 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200328
329done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200330 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200331 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200332}
333
334static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
335{
336 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
337
338 BT_DBG("%s status 0x%x", hdev->name, rp->status);
339
340 if (rp->status)
341 return;
342
343 memcpy(hdev->dev_class, rp->dev_class, 3);
344
345 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
346 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
347}
348
349static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
350{
351 __u8 status = *((__u8 *) skb->data);
352 void *sent;
353
354 BT_DBG("%s status 0x%x", hdev->name, status);
355
356 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
357 if (!sent)
358 return;
359
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100360 hci_dev_lock(hdev);
361
362 if (status == 0)
363 memcpy(hdev->dev_class, sent, 3);
364
365 if (test_bit(HCI_MGMT, &hdev->dev_flags))
366 mgmt_set_class_of_dev_complete(hdev, sent, status);
367
368 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200369}
370
371static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
372{
373 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375
376 BT_DBG("%s status 0x%x", hdev->name, rp->status);
377
378 if (rp->status)
379 return;
380
381 setting = __le16_to_cpu(rp->voice_setting);
382
Marcel Holtmannf383f272008-07-14 20:13:47 +0200383 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384 return;
385
386 hdev->voice_setting = setting;
387
388 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
389
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200390 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200391 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392}
393
394static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
395{
396 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200397 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 void *sent;
399
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200400 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401
Marcel Holtmannf383f272008-07-14 20:13:47 +0200402 if (status)
403 return;
404
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200405 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
406 if (!sent)
407 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Marcel Holtmannf383f272008-07-14 20:13:47 +0200409 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
Marcel Holtmannf383f272008-07-14 20:13:47 +0200411 if (hdev->voice_setting == setting)
412 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413
Marcel Holtmannf383f272008-07-14 20:13:47 +0200414 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415
Marcel Holtmannf383f272008-07-14 20:13:47 +0200416 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
417
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200418 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200419 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420}
421
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200422static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200424 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200426 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427
Johan Hedberg23bb5762010-12-21 23:01:27 +0200428 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429}
430
Marcel Holtmann333140b2008-07-14 20:13:48 +0200431static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
432{
433 __u8 status = *((__u8 *) skb->data);
434 void *sent;
435
436 BT_DBG("%s status 0x%x", hdev->name, status);
437
Marcel Holtmann333140b2008-07-14 20:13:48 +0200438 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
439 if (!sent)
440 return;
441
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200442 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200443 mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status);
444 else if (!status) {
445 if (*((u8 *) sent))
446 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
447 else
448 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
449 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200450}
451
Johan Hedbergd5859e22011-01-25 01:19:58 +0200452static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
453{
454 if (hdev->features[6] & LMP_EXT_INQ)
455 return 2;
456
457 if (hdev->features[3] & LMP_RSSI_INQ)
458 return 1;
459
460 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
461 hdev->lmp_subver == 0x0757)
462 return 1;
463
464 if (hdev->manufacturer == 15) {
465 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
466 return 1;
467 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
468 return 1;
469 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
470 return 1;
471 }
472
473 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
474 hdev->lmp_subver == 0x1805)
475 return 1;
476
477 return 0;
478}
479
480static void hci_setup_inquiry_mode(struct hci_dev *hdev)
481{
482 u8 mode;
483
484 mode = hci_get_inquiry_mode(hdev);
485
486 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
487}
488
489static void hci_setup_event_mask(struct hci_dev *hdev)
490{
491 /* The second byte is 0xff instead of 0x9f (two reserved bits
492 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
493 * command otherwise */
494 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
495
Ville Tervo6de6c182011-05-27 11:16:21 +0300496 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
497 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200498 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300499 return;
500
501 events[4] |= 0x01; /* Flow Specification Complete */
502 events[4] |= 0x02; /* Inquiry Result with RSSI */
503 events[4] |= 0x04; /* Read Remote Extended Features Complete */
504 events[5] |= 0x08; /* Synchronous Connection Complete */
505 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200506
507 if (hdev->features[3] & LMP_RSSI_INQ)
508 events[4] |= 0x04; /* Inquiry Result with RSSI */
509
510 if (hdev->features[5] & LMP_SNIFF_SUBR)
511 events[5] |= 0x20; /* Sniff Subrating */
512
513 if (hdev->features[5] & LMP_PAUSE_ENC)
514 events[5] |= 0x80; /* Encryption Key Refresh Complete */
515
516 if (hdev->features[6] & LMP_EXT_INQ)
517 events[5] |= 0x40; /* Extended Inquiry Result */
518
519 if (hdev->features[6] & LMP_NO_FLUSH)
520 events[7] |= 0x01; /* Enhanced Flush Complete */
521
522 if (hdev->features[7] & LMP_LSTO)
523 events[6] |= 0x80; /* Link Supervision Timeout Changed */
524
525 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
526 events[6] |= 0x01; /* IO Capability Request */
527 events[6] |= 0x02; /* IO Capability Response */
528 events[6] |= 0x04; /* User Confirmation Request */
529 events[6] |= 0x08; /* User Passkey Request */
530 events[6] |= 0x10; /* Remote OOB Data Request */
531 events[6] |= 0x20; /* Simple Pairing Complete */
532 events[7] |= 0x04; /* User Passkey Notification */
533 events[7] |= 0x08; /* Keypress Notification */
534 events[7] |= 0x10; /* Remote Host Supported
535 * Features Notification */
536 }
537
538 if (hdev->features[4] & LMP_LE)
539 events[7] |= 0x20; /* LE Meta-Event */
540
541 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
542}
543
544static void hci_setup(struct hci_dev *hdev)
545{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200546 if (hdev->dev_type != HCI_BREDR)
547 return;
548
Johan Hedbergd5859e22011-01-25 01:19:58 +0200549 hci_setup_event_mask(hdev);
550
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200551 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200552 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
553
Johan Hedberg54d04db2012-02-22 15:47:48 +0200554 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
555 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
556 u8 mode = 0x01;
557 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300558 sizeof(mode), &mode);
Johan Hedberg54d04db2012-02-22 15:47:48 +0200559 } else {
560 struct hci_cp_write_eir cp;
561
562 memset(hdev->eir, 0, sizeof(hdev->eir));
563 memset(&cp, 0, sizeof(cp));
564
565 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
566 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200567 }
568
569 if (hdev->features[3] & LMP_RSSI_INQ)
570 hci_setup_inquiry_mode(hdev);
571
572 if (hdev->features[7] & LMP_INQ_TX_PWR)
573 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300574
575 if (hdev->features[7] & LMP_EXTFEATURES) {
576 struct hci_cp_read_local_ext_features cp;
577
578 cp.page = 0x01;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300579 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp),
580 &cp);
Andre Guedes971e3a42011-06-30 19:20:52 -0300581 }
Andre Guedese6100a22011-06-30 19:20:54 -0300582
Johan Hedberg47990ea2012-02-22 11:58:37 +0200583 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
584 u8 enable = 1;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300585 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
586 &enable);
Johan Hedberg47990ea2012-02-22 11:58:37 +0200587 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200588}
589
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200590static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
591{
592 struct hci_rp_read_local_version *rp = (void *) skb->data;
593
594 BT_DBG("%s status 0x%x", hdev->name, rp->status);
595
596 if (rp->status)
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200597 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200598
599 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200600 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200601 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200602 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200603 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200604
605 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
606 hdev->manufacturer,
607 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200608
609 if (test_bit(HCI_INIT, &hdev->flags))
610 hci_setup(hdev);
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200611
612done:
613 hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200614}
615
616static void hci_setup_link_policy(struct hci_dev *hdev)
617{
618 u16 link_policy = 0;
619
620 if (hdev->features[0] & LMP_RSWITCH)
621 link_policy |= HCI_LP_RSWITCH;
622 if (hdev->features[0] & LMP_HOLD)
623 link_policy |= HCI_LP_HOLD;
624 if (hdev->features[0] & LMP_SNIFF)
625 link_policy |= HCI_LP_SNIFF;
626 if (hdev->features[1] & LMP_PARK)
627 link_policy |= HCI_LP_PARK;
628
629 link_policy = cpu_to_le16(link_policy);
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300630 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(link_policy),
631 &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200632}
633
634static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
635{
636 struct hci_rp_read_local_commands *rp = (void *) skb->data;
637
638 BT_DBG("%s status 0x%x", hdev->name, rp->status);
639
640 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200641 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200642
643 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200644
645 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
646 hci_setup_link_policy(hdev);
647
648done:
649 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200650}
651
652static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
653{
654 struct hci_rp_read_local_features *rp = (void *) skb->data;
655
656 BT_DBG("%s status 0x%x", hdev->name, rp->status);
657
658 if (rp->status)
659 return;
660
661 memcpy(hdev->features, rp->features, 8);
662
663 /* Adjust default settings according to features
664 * supported by device. */
665
666 if (hdev->features[0] & LMP_3SLOT)
667 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
668
669 if (hdev->features[0] & LMP_5SLOT)
670 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
671
672 if (hdev->features[1] & LMP_HV2) {
673 hdev->pkt_type |= (HCI_HV2);
674 hdev->esco_type |= (ESCO_HV2);
675 }
676
677 if (hdev->features[1] & LMP_HV3) {
678 hdev->pkt_type |= (HCI_HV3);
679 hdev->esco_type |= (ESCO_HV3);
680 }
681
682 if (hdev->features[3] & LMP_ESCO)
683 hdev->esco_type |= (ESCO_EV3);
684
685 if (hdev->features[4] & LMP_EV4)
686 hdev->esco_type |= (ESCO_EV4);
687
688 if (hdev->features[4] & LMP_EV5)
689 hdev->esco_type |= (ESCO_EV5);
690
Marcel Holtmannefc76882009-02-06 09:13:37 +0100691 if (hdev->features[5] & LMP_EDR_ESCO_2M)
692 hdev->esco_type |= (ESCO_2EV3);
693
694 if (hdev->features[5] & LMP_EDR_ESCO_3M)
695 hdev->esco_type |= (ESCO_3EV3);
696
697 if (hdev->features[5] & LMP_EDR_3S_ESCO)
698 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
699
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200700 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
701 hdev->features[0], hdev->features[1],
702 hdev->features[2], hdev->features[3],
703 hdev->features[4], hdev->features[5],
704 hdev->features[6], hdev->features[7]);
705}
706
Johan Hedberg8f984df2012-02-28 01:07:22 +0200707static void hci_set_le_support(struct hci_dev *hdev)
708{
709 struct hci_cp_write_le_host_supported cp;
710
711 memset(&cp, 0, sizeof(cp));
712
713 if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
714 cp.le = 1;
715 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
716 }
717
718 if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300719 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
720 &cp);
Johan Hedberg8f984df2012-02-28 01:07:22 +0200721}
722
Andre Guedes971e3a42011-06-30 19:20:52 -0300723static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
724 struct sk_buff *skb)
725{
726 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
727
728 BT_DBG("%s status 0x%x", hdev->name, rp->status);
729
730 if (rp->status)
Johan Hedberg8f984df2012-02-28 01:07:22 +0200731 goto done;
Andre Guedes971e3a42011-06-30 19:20:52 -0300732
Andre Guedesb5b32b62011-12-30 10:34:04 -0300733 switch (rp->page) {
734 case 0:
735 memcpy(hdev->features, rp->features, 8);
736 break;
737 case 1:
738 memcpy(hdev->host_features, rp->features, 8);
739 break;
740 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300741
Johan Hedberg8f984df2012-02-28 01:07:22 +0200742 if (test_bit(HCI_INIT, &hdev->flags) && hdev->features[4] & LMP_LE)
743 hci_set_le_support(hdev);
744
745done:
Andre Guedes971e3a42011-06-30 19:20:52 -0300746 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
747}
748
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200749static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
750 struct sk_buff *skb)
751{
752 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
753
754 BT_DBG("%s status 0x%x", hdev->name, rp->status);
755
756 if (rp->status)
757 return;
758
759 hdev->flow_ctl_mode = rp->mode;
760
761 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
762}
763
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200764static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
765{
766 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
767
768 BT_DBG("%s status 0x%x", hdev->name, rp->status);
769
770 if (rp->status)
771 return;
772
773 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
774 hdev->sco_mtu = rp->sco_mtu;
775 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
776 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
777
778 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
779 hdev->sco_mtu = 64;
780 hdev->sco_pkts = 8;
781 }
782
783 hdev->acl_cnt = hdev->acl_pkts;
784 hdev->sco_cnt = hdev->sco_pkts;
785
786 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
787 hdev->acl_mtu, hdev->acl_pkts,
788 hdev->sco_mtu, hdev->sco_pkts);
789}
790
791static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
792{
793 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
794
795 BT_DBG("%s status 0x%x", hdev->name, rp->status);
796
797 if (!rp->status)
798 bacpy(&hdev->bdaddr, &rp->bdaddr);
799
Johan Hedberg23bb5762010-12-21 23:01:27 +0200800 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
801}
802
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200803static void hci_cc_read_data_block_size(struct hci_dev *hdev,
804 struct sk_buff *skb)
805{
806 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
807
808 BT_DBG("%s status 0x%x", hdev->name, rp->status);
809
810 if (rp->status)
811 return;
812
813 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
814 hdev->block_len = __le16_to_cpu(rp->block_len);
815 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
816
817 hdev->block_cnt = hdev->num_blocks;
818
819 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
820 hdev->block_cnt, hdev->block_len);
821
822 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
823}
824
Johan Hedberg23bb5762010-12-21 23:01:27 +0200825static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
826{
827 __u8 status = *((__u8 *) skb->data);
828
829 BT_DBG("%s status 0x%x", hdev->name, status);
830
831 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200832}
833
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300834static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
835 struct sk_buff *skb)
836{
837 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
838
839 BT_DBG("%s status 0x%x", hdev->name, rp->status);
840
841 if (rp->status)
842 return;
843
844 hdev->amp_status = rp->amp_status;
845 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
846 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
847 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
848 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
849 hdev->amp_type = rp->amp_type;
850 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
851 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
852 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
853 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
854
855 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
856}
857
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200858static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
859 struct sk_buff *skb)
860{
861 __u8 status = *((__u8 *) skb->data);
862
863 BT_DBG("%s status 0x%x", hdev->name, status);
864
865 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
866}
867
Johan Hedbergd5859e22011-01-25 01:19:58 +0200868static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
869{
870 __u8 status = *((__u8 *) skb->data);
871
872 BT_DBG("%s status 0x%x", hdev->name, status);
873
874 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
875}
876
877static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
878 struct sk_buff *skb)
879{
880 __u8 status = *((__u8 *) skb->data);
881
882 BT_DBG("%s status 0x%x", hdev->name, status);
883
884 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
885}
886
887static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
888 struct sk_buff *skb)
889{
890 __u8 status = *((__u8 *) skb->data);
891
892 BT_DBG("%s status 0x%x", hdev->name, status);
893
894 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
895}
896
897static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
898{
899 __u8 status = *((__u8 *) skb->data);
900
901 BT_DBG("%s status 0x%x", hdev->name, status);
902
903 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
904}
905
Johan Hedberg980e1a52011-01-22 06:10:07 +0200906static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
907{
908 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
909 struct hci_cp_pin_code_reply *cp;
910 struct hci_conn *conn;
911
912 BT_DBG("%s status 0x%x", hdev->name, rp->status);
913
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200914 hci_dev_lock(hdev);
915
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200916 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200917 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200918
919 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200920 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200921
922 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
923 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200924 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200925
926 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
927 if (conn)
928 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200929
930unlock:
931 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200932}
933
934static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
935{
936 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
937
938 BT_DBG("%s status 0x%x", hdev->name, rp->status);
939
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200940 hci_dev_lock(hdev);
941
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200942 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200943 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200944 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200945
946 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200947}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200948
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300949static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
950 struct sk_buff *skb)
951{
952 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
953
954 BT_DBG("%s status 0x%x", hdev->name, rp->status);
955
956 if (rp->status)
957 return;
958
959 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
960 hdev->le_pkts = rp->le_max_pkt;
961
962 hdev->le_cnt = hdev->le_pkts;
963
964 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
965
966 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
967}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200968
Johan Hedberga5c29682011-02-19 12:05:57 -0300969static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
970{
971 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
972
973 BT_DBG("%s status 0x%x", hdev->name, rp->status);
974
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200975 hci_dev_lock(hdev);
976
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200977 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300978 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
979 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200980
981 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300982}
983
984static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
985 struct sk_buff *skb)
986{
987 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
988
989 BT_DBG("%s status 0x%x", hdev->name, rp->status);
990
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200991 hci_dev_lock(hdev);
992
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200993 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200994 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300995 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200996
997 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300998}
999
Brian Gix1143d452011-11-23 08:28:34 -08001000static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
1001{
1002 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1003
1004 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1005
1006 hci_dev_lock(hdev);
1007
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001008 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001009 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001010 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001011
1012 hci_dev_unlock(hdev);
1013}
1014
1015static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1016 struct sk_buff *skb)
1017{
1018 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1019
1020 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1021
1022 hci_dev_lock(hdev);
1023
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001024 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001025 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001026 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001027
1028 hci_dev_unlock(hdev);
1029}
1030
Szymon Jancc35938b2011-03-22 13:12:21 +01001031static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1032 struct sk_buff *skb)
1033{
1034 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1035
1036 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1037
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001038 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001039 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001040 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001041 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001042}
1043
Andre Guedes07f7fa52011-12-02 21:13:31 +09001044static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1045{
1046 __u8 status = *((__u8 *) skb->data);
1047
1048 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001049
1050 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001051
1052 if (status) {
1053 hci_dev_lock(hdev);
1054 mgmt_start_discovery_failed(hdev, status);
1055 hci_dev_unlock(hdev);
1056 return;
1057 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001058}
1059
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001060static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1061 struct sk_buff *skb)
1062{
1063 struct hci_cp_le_set_scan_enable *cp;
1064 __u8 status = *((__u8 *) skb->data);
1065
1066 BT_DBG("%s status 0x%x", hdev->name, status);
1067
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001068 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1069 if (!cp)
1070 return;
1071
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001072 switch (cp->enable) {
1073 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001074 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1075
Andre Guedes3fd24152012-02-03 17:48:01 -03001076 if (status) {
1077 hci_dev_lock(hdev);
1078 mgmt_start_discovery_failed(hdev, status);
1079 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001080 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001081 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001082
Andre Guedesd23264a2011-11-25 20:53:38 -03001083 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1084
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001085 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001086
1087 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001088 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001089 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001090 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001091 break;
1092
1093 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001094 if (status)
1095 return;
1096
Andre Guedesd23264a2011-11-25 20:53:38 -03001097 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1098
Andre Guedesd0843292012-01-02 19:18:11 -03001099 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001100
Andre Guedesbc3dd332012-03-06 19:37:06 -03001101 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
1102 hdev->discovery.state == DISCOVERY_FINDING) {
Andre Guedes5e0452c2012-02-17 20:39:38 -03001103 mgmt_interleaved_discovery(hdev);
1104 } else {
1105 hci_dev_lock(hdev);
1106 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1107 hci_dev_unlock(hdev);
1108 }
1109
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001110 break;
1111
1112 default:
1113 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1114 break;
Andre Guedes35815082011-05-26 16:23:53 -03001115 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001116}
1117
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001118static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1119{
1120 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1121
1122 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1123
1124 if (rp->status)
1125 return;
1126
1127 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1128}
1129
1130static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1131{
1132 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1133
1134 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1135
1136 if (rp->status)
1137 return;
1138
1139 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1140}
1141
Andre Guedesf9b49302011-06-30 19:20:53 -03001142static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1143 struct sk_buff *skb)
1144{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001145 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001146 __u8 status = *((__u8 *) skb->data);
1147
1148 BT_DBG("%s status 0x%x", hdev->name, status);
1149
Johan Hedberg06199cf2012-02-22 16:37:11 +02001150 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001151 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001152 return;
1153
Johan Hedberg8f984df2012-02-28 01:07:22 +02001154 if (!status) {
1155 if (sent->le)
1156 hdev->host_features[0] |= LMP_HOST_LE;
1157 else
1158 hdev->host_features[0] &= ~LMP_HOST_LE;
1159 }
1160
1161 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
1162 !test_bit(HCI_INIT, &hdev->flags))
1163 mgmt_le_enable_complete(hdev, sent->le, status);
1164
1165 hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001166}
1167
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001168static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1169{
1170 BT_DBG("%s status 0x%x", hdev->name, status);
1171
1172 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001173 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001174 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001175 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001176 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001177 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001178 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001179 return;
1180 }
1181
Andre Guedes89352e72011-11-04 14:16:53 -03001182 set_bit(HCI_INQUIRY, &hdev->flags);
1183
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001184 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001185 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001186 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001187}
1188
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1190{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001191 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001194 BT_DBG("%s status 0x%x", hdev->name, status);
1195
1196 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 if (!cp)
1198 return;
1199
1200 hci_dev_lock(hdev);
1201
1202 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1203
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001204 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205
1206 if (status) {
1207 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001208 if (status != 0x0c || conn->attempt > 2) {
1209 conn->state = BT_CLOSED;
1210 hci_proto_connect_cfm(conn, status);
1211 hci_conn_del(conn);
1212 } else
1213 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 }
1215 } else {
1216 if (!conn) {
1217 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1218 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001219 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 conn->link_mode |= HCI_LM_MASTER;
1221 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001222 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 }
1224 }
1225
1226 hci_dev_unlock(hdev);
1227}
1228
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001229static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001231 struct hci_cp_add_sco *cp;
1232 struct hci_conn *acl, *sco;
1233 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001235 BT_DBG("%s status 0x%x", hdev->name, status);
1236
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001237 if (!status)
1238 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001240 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1241 if (!cp)
1242 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001244 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001246 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001247
1248 hci_dev_lock(hdev);
1249
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001250 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001251 if (acl) {
1252 sco = acl->link;
1253 if (sco) {
1254 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001255
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001256 hci_proto_connect_cfm(sco, status);
1257 hci_conn_del(sco);
1258 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001259 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001260
1261 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262}
1263
Marcel Holtmannf8558552008-07-14 20:13:49 +02001264static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1265{
1266 struct hci_cp_auth_requested *cp;
1267 struct hci_conn *conn;
1268
1269 BT_DBG("%s status 0x%x", hdev->name, status);
1270
1271 if (!status)
1272 return;
1273
1274 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1275 if (!cp)
1276 return;
1277
1278 hci_dev_lock(hdev);
1279
1280 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1281 if (conn) {
1282 if (conn->state == BT_CONFIG) {
1283 hci_proto_connect_cfm(conn, status);
1284 hci_conn_put(conn);
1285 }
1286 }
1287
1288 hci_dev_unlock(hdev);
1289}
1290
1291static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1292{
1293 struct hci_cp_set_conn_encrypt *cp;
1294 struct hci_conn *conn;
1295
1296 BT_DBG("%s status 0x%x", hdev->name, status);
1297
1298 if (!status)
1299 return;
1300
1301 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1302 if (!cp)
1303 return;
1304
1305 hci_dev_lock(hdev);
1306
1307 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1308 if (conn) {
1309 if (conn->state == BT_CONFIG) {
1310 hci_proto_connect_cfm(conn, status);
1311 hci_conn_put(conn);
1312 }
1313 }
1314
1315 hci_dev_unlock(hdev);
1316}
1317
Johan Hedberg127178d2010-11-18 22:22:29 +02001318static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001319 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001320{
Johan Hedberg392599b2010-11-18 22:22:28 +02001321 if (conn->state != BT_CONFIG || !conn->out)
1322 return 0;
1323
Johan Hedberg765c2a92011-01-19 12:06:52 +05301324 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001325 return 0;
1326
1327 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001328 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001329 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001330 conn->pending_sec_level != BT_SECURITY_HIGH &&
1331 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001332 return 0;
1333
Johan Hedberg392599b2010-11-18 22:22:28 +02001334 return 1;
1335}
1336
Gustavo F. Padovan00abfe42012-03-01 00:37:10 -03001337static inline int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001338 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001339{
1340 struct hci_cp_remote_name_req cp;
1341
1342 memset(&cp, 0, sizeof(cp));
1343
1344 bacpy(&cp.bdaddr, &e->data.bdaddr);
1345 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1346 cp.pscan_mode = e->data.pscan_mode;
1347 cp.clock_offset = e->data.clock_offset;
1348
1349 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1350}
1351
Johan Hedbergb644ba32012-01-17 21:48:47 +02001352static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001353{
1354 struct discovery_state *discov = &hdev->discovery;
1355 struct inquiry_entry *e;
1356
Johan Hedbergb644ba32012-01-17 21:48:47 +02001357 if (list_empty(&discov->resolve))
1358 return false;
1359
1360 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1361 if (hci_resolve_name(hdev, e) == 0) {
1362 e->name_state = NAME_PENDING;
1363 return true;
1364 }
1365
1366 return false;
1367}
1368
1369static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001370 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001371{
1372 struct discovery_state *discov = &hdev->discovery;
1373 struct inquiry_entry *e;
1374
1375 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001376 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1377 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001378
1379 if (discov->state == DISCOVERY_STOPPED)
1380 return;
1381
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001382 if (discov->state == DISCOVERY_STOPPING)
1383 goto discov_complete;
1384
1385 if (discov->state != DISCOVERY_RESOLVING)
1386 return;
1387
1388 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1389 if (e) {
1390 e->name_state = NAME_KNOWN;
1391 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001392 if (name)
1393 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001394 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001395 }
1396
Johan Hedbergb644ba32012-01-17 21:48:47 +02001397 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001398 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001399
1400discov_complete:
1401 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1402}
1403
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001404static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1405{
Johan Hedberg127178d2010-11-18 22:22:29 +02001406 struct hci_cp_remote_name_req *cp;
1407 struct hci_conn *conn;
1408
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001409 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001410
1411 /* If successful wait for the name req complete event before
1412 * checking for the need to do authentication */
1413 if (!status)
1414 return;
1415
1416 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1417 if (!cp)
1418 return;
1419
1420 hci_dev_lock(hdev);
1421
1422 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001423
1424 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1425 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1426
Johan Hedberg79c6c702011-04-28 11:28:55 -07001427 if (!conn)
1428 goto unlock;
1429
1430 if (!hci_outgoing_auth_needed(hdev, conn))
1431 goto unlock;
1432
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001433 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001434 struct hci_cp_auth_requested cp;
1435 cp.handle = __cpu_to_le16(conn->handle);
1436 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1437 }
1438
Johan Hedberg79c6c702011-04-28 11:28:55 -07001439unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001440 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001441}
1442
Marcel Holtmann769be972008-07-14 20:13:49 +02001443static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1444{
1445 struct hci_cp_read_remote_features *cp;
1446 struct hci_conn *conn;
1447
1448 BT_DBG("%s status 0x%x", hdev->name, status);
1449
1450 if (!status)
1451 return;
1452
1453 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1454 if (!cp)
1455 return;
1456
1457 hci_dev_lock(hdev);
1458
1459 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1460 if (conn) {
1461 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001462 hci_proto_connect_cfm(conn, status);
1463 hci_conn_put(conn);
1464 }
1465 }
1466
1467 hci_dev_unlock(hdev);
1468}
1469
1470static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1471{
1472 struct hci_cp_read_remote_ext_features *cp;
1473 struct hci_conn *conn;
1474
1475 BT_DBG("%s status 0x%x", hdev->name, status);
1476
1477 if (!status)
1478 return;
1479
1480 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1481 if (!cp)
1482 return;
1483
1484 hci_dev_lock(hdev);
1485
1486 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1487 if (conn) {
1488 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001489 hci_proto_connect_cfm(conn, status);
1490 hci_conn_put(conn);
1491 }
1492 }
1493
1494 hci_dev_unlock(hdev);
1495}
1496
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001497static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1498{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001499 struct hci_cp_setup_sync_conn *cp;
1500 struct hci_conn *acl, *sco;
1501 __u16 handle;
1502
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001503 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001504
1505 if (!status)
1506 return;
1507
1508 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1509 if (!cp)
1510 return;
1511
1512 handle = __le16_to_cpu(cp->handle);
1513
1514 BT_DBG("%s handle %d", hdev->name, handle);
1515
1516 hci_dev_lock(hdev);
1517
1518 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001519 if (acl) {
1520 sco = acl->link;
1521 if (sco) {
1522 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001523
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001524 hci_proto_connect_cfm(sco, status);
1525 hci_conn_del(sco);
1526 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001527 }
1528
1529 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001530}
1531
1532static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1533{
1534 struct hci_cp_sniff_mode *cp;
1535 struct hci_conn *conn;
1536
1537 BT_DBG("%s status 0x%x", hdev->name, status);
1538
1539 if (!status)
1540 return;
1541
1542 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1543 if (!cp)
1544 return;
1545
1546 hci_dev_lock(hdev);
1547
1548 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001549 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001550 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001551
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001552 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001553 hci_sco_setup(conn, status);
1554 }
1555
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001556 hci_dev_unlock(hdev);
1557}
1558
1559static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1560{
1561 struct hci_cp_exit_sniff_mode *cp;
1562 struct hci_conn *conn;
1563
1564 BT_DBG("%s status 0x%x", hdev->name, status);
1565
1566 if (!status)
1567 return;
1568
1569 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1570 if (!cp)
1571 return;
1572
1573 hci_dev_lock(hdev);
1574
1575 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001576 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001577 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001578
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001579 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001580 hci_sco_setup(conn, status);
1581 }
1582
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001583 hci_dev_unlock(hdev);
1584}
1585
Johan Hedberg88c3df12012-02-09 14:27:38 +02001586static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1587{
1588 struct hci_cp_disconnect *cp;
1589 struct hci_conn *conn;
1590
1591 if (!status)
1592 return;
1593
1594 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1595 if (!cp)
1596 return;
1597
1598 hci_dev_lock(hdev);
1599
1600 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1601 if (conn)
1602 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001603 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001604
1605 hci_dev_unlock(hdev);
1606}
1607
Ville Tervofcd89c02011-02-10 22:38:47 -03001608static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1609{
1610 struct hci_cp_le_create_conn *cp;
1611 struct hci_conn *conn;
1612
1613 BT_DBG("%s status 0x%x", hdev->name, status);
1614
1615 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1616 if (!cp)
1617 return;
1618
1619 hci_dev_lock(hdev);
1620
1621 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1622
1623 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1624 conn);
1625
1626 if (status) {
1627 if (conn && conn->state == BT_CONNECT) {
1628 conn->state = BT_CLOSED;
1629 hci_proto_connect_cfm(conn, status);
1630 hci_conn_del(conn);
1631 }
1632 } else {
1633 if (!conn) {
1634 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001635 if (conn) {
1636 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001637 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001638 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001639 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001640 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001641 }
1642 }
1643
1644 hci_dev_unlock(hdev);
1645}
1646
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001647static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1648{
1649 BT_DBG("%s status 0x%x", hdev->name, status);
1650}
1651
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001652static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1653{
1654 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001655 struct discovery_state *discov = &hdev->discovery;
1656 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001657
1658 BT_DBG("%s status %d", hdev->name, status);
1659
Johan Hedberg23bb5762010-12-21 23:01:27 +02001660 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001661
1662 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001663
1664 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1665 return;
1666
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001667 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001668 return;
1669
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001670 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001671
Andre Guedes343f9352012-02-17 20:39:37 -03001672 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001673 goto unlock;
1674
1675 if (list_empty(&discov->resolve)) {
1676 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1677 goto unlock;
1678 }
1679
1680 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1681 if (e && hci_resolve_name(hdev, e) == 0) {
1682 e->name_state = NAME_PENDING;
1683 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1684 } else {
1685 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1686 }
1687
1688unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001689 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001690}
1691
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1693{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001694 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001695 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 int num_rsp = *((__u8 *) skb->data);
1697
1698 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1699
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001700 if (!num_rsp)
1701 return;
1702
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001704
Johan Hedberge17acd42011-03-30 23:57:16 +03001705 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001706 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001707
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 bacpy(&data.bdaddr, &info->bdaddr);
1709 data.pscan_rep_mode = info->pscan_rep_mode;
1710 data.pscan_period_mode = info->pscan_period_mode;
1711 data.pscan_mode = info->pscan_mode;
1712 memcpy(data.dev_class, info->dev_class, 3);
1713 data.clock_offset = info->clock_offset;
1714 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001715 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001716
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001717 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001718 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001719 info->dev_class, 0, !name_known, ssp, NULL,
1720 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001722
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 hci_dev_unlock(hdev);
1724}
1725
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001726static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001728 struct hci_ev_conn_complete *ev = (void *) skb->data;
1729 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001731 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001732
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001734
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001735 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001736 if (!conn) {
1737 if (ev->link_type != SCO_LINK)
1738 goto unlock;
1739
1740 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1741 if (!conn)
1742 goto unlock;
1743
1744 conn->type = SCO_LINK;
1745 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001746
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001747 if (!ev->status) {
1748 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001749
1750 if (conn->type == ACL_LINK) {
1751 conn->state = BT_CONFIG;
1752 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001753 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001754 } else
1755 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001756
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001757 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001758 hci_conn_add_sysfs(conn);
1759
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001760 if (test_bit(HCI_AUTH, &hdev->flags))
1761 conn->link_mode |= HCI_LM_AUTH;
1762
1763 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1764 conn->link_mode |= HCI_LM_ENCRYPT;
1765
1766 /* Get remote features */
1767 if (conn->type == ACL_LINK) {
1768 struct hci_cp_read_remote_features cp;
1769 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001770 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001771 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001772 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001773
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001774 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001775 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001776 struct hci_cp_change_conn_ptype cp;
1777 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001778 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001779 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1780 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001781 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001782 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001783 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001784 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001785 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001786 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001787 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001788
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001789 if (conn->type == ACL_LINK)
1790 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001791
Marcel Holtmann769be972008-07-14 20:13:49 +02001792 if (ev->status) {
1793 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001794 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001795 } else if (ev->link_type != ACL_LINK)
1796 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001797
1798unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001800
1801 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802}
1803
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1805{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001806 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 int mask = hdev->link_mode;
1808
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001809 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1810 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811
1812 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1813
Szymon Janc138d22e2011-02-17 16:44:23 +01001814 if ((mask & HCI_LM_ACCEPT) &&
1815 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001817 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819
1820 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001821
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001822 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1823 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001824 memcpy(ie->data.dev_class, ev->dev_class, 3);
1825
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1827 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001828 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1829 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001830 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 hci_dev_unlock(hdev);
1832 return;
1833 }
1834 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001835
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 memcpy(conn->dev_class, ev->dev_class, 3);
1837 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001838
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839 hci_dev_unlock(hdev);
1840
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001841 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1842 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001844 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001846 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1847 cp.role = 0x00; /* Become master */
1848 else
1849 cp.role = 0x01; /* Remain slave */
1850
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001851 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1852 &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001853 } else {
1854 struct hci_cp_accept_sync_conn_req cp;
1855
1856 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001857 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001858
1859 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1860 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1861 cp.max_latency = cpu_to_le16(0xffff);
1862 cp.content_format = cpu_to_le16(hdev->voice_setting);
1863 cp.retrans_effort = 0xff;
1864
1865 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001866 sizeof(cp), &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001867 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 } else {
1869 /* Connection rejected */
1870 struct hci_cp_reject_conn_req cp;
1871
1872 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001873 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001874 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875 }
1876}
1877
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1879{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001880 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001881 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882
1883 BT_DBG("%s status %d", hdev->name, ev->status);
1884
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 hci_dev_lock(hdev);
1886
Marcel Holtmann04837f62006-07-03 10:02:33 +02001887 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001888 if (!conn)
1889 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001890
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001891 if (ev->status == 0)
1892 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893
Johan Hedbergb644ba32012-01-17 21:48:47 +02001894 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1895 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001896 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001897 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1898 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001899 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001900 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001901 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001902 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001903
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001904 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301905 if (conn->type == ACL_LINK && conn->flush_key)
1906 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001907 hci_proto_disconn_cfm(conn, ev->reason);
1908 hci_conn_del(conn);
1909 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001910
1911unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 hci_dev_unlock(hdev);
1913}
1914
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001915static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1916{
1917 struct hci_ev_auth_complete *ev = (void *) skb->data;
1918 struct hci_conn *conn;
1919
1920 BT_DBG("%s status %d", hdev->name, ev->status);
1921
1922 hci_dev_lock(hdev);
1923
1924 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001925 if (!conn)
1926 goto unlock;
1927
1928 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001929 if (!hci_conn_ssp_enabled(conn) &&
1930 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001931 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001932 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001933 conn->link_mode |= HCI_LM_AUTH;
1934 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001935 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001936 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001937 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001938 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001939 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001940
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001941 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1942 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001943
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001944 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001945 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001946 struct hci_cp_set_conn_encrypt cp;
1947 cp.handle = ev->handle;
1948 cp.encrypt = 0x01;
1949 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1950 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001951 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001952 conn->state = BT_CONNECTED;
1953 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001954 hci_conn_put(conn);
1955 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001956 } else {
1957 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001958
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001959 hci_conn_hold(conn);
1960 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1961 hci_conn_put(conn);
1962 }
1963
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001964 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001965 if (!ev->status) {
1966 struct hci_cp_set_conn_encrypt cp;
1967 cp.handle = ev->handle;
1968 cp.encrypt = 0x01;
1969 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1970 &cp);
1971 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001972 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001973 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001974 }
1975 }
1976
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001977unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001978 hci_dev_unlock(hdev);
1979}
1980
1981static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1982{
Johan Hedberg127178d2010-11-18 22:22:29 +02001983 struct hci_ev_remote_name *ev = (void *) skb->data;
1984 struct hci_conn *conn;
1985
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001986 BT_DBG("%s", hdev->name);
1987
1988 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001989
1990 hci_dev_lock(hdev);
1991
1992 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001993
1994 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1995 goto check_auth;
1996
1997 if (ev->status == 0)
1998 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001999 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002000 else
2001 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2002
2003check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002004 if (!conn)
2005 goto unlock;
2006
2007 if (!hci_outgoing_auth_needed(hdev, conn))
2008 goto unlock;
2009
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002010 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002011 struct hci_cp_auth_requested cp;
2012 cp.handle = __cpu_to_le16(conn->handle);
2013 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2014 }
2015
Johan Hedberg79c6c702011-04-28 11:28:55 -07002016unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002017 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002018}
2019
2020static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2021{
2022 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2023 struct hci_conn *conn;
2024
2025 BT_DBG("%s status %d", hdev->name, ev->status);
2026
2027 hci_dev_lock(hdev);
2028
2029 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2030 if (conn) {
2031 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002032 if (ev->encrypt) {
2033 /* Encryption implies authentication */
2034 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002035 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002036 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002037 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002038 conn->link_mode &= ~HCI_LM_ENCRYPT;
2039 }
2040
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002041 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002042
Marcel Holtmannf8558552008-07-14 20:13:49 +02002043 if (conn->state == BT_CONFIG) {
2044 if (!ev->status)
2045 conn->state = BT_CONNECTED;
2046
2047 hci_proto_connect_cfm(conn, ev->status);
2048 hci_conn_put(conn);
2049 } else
2050 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002051 }
2052
2053 hci_dev_unlock(hdev);
2054}
2055
2056static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2057{
2058 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2059 struct hci_conn *conn;
2060
2061 BT_DBG("%s status %d", hdev->name, ev->status);
2062
2063 hci_dev_lock(hdev);
2064
2065 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2066 if (conn) {
2067 if (!ev->status)
2068 conn->link_mode |= HCI_LM_SECURE;
2069
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002070 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002071
2072 hci_key_change_cfm(conn, ev->status);
2073 }
2074
2075 hci_dev_unlock(hdev);
2076}
2077
2078static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2079{
2080 struct hci_ev_remote_features *ev = (void *) skb->data;
2081 struct hci_conn *conn;
2082
2083 BT_DBG("%s status %d", hdev->name, ev->status);
2084
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002085 hci_dev_lock(hdev);
2086
2087 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002088 if (!conn)
2089 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002090
Johan Hedbergccd556f2010-11-10 17:11:51 +02002091 if (!ev->status)
2092 memcpy(conn->features, ev->features, 8);
2093
2094 if (conn->state != BT_CONFIG)
2095 goto unlock;
2096
2097 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2098 struct hci_cp_read_remote_ext_features cp;
2099 cp.handle = ev->handle;
2100 cp.page = 0x01;
2101 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002102 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002103 goto unlock;
2104 }
2105
Johan Hedberg127178d2010-11-18 22:22:29 +02002106 if (!ev->status) {
2107 struct hci_cp_remote_name_req cp;
2108 memset(&cp, 0, sizeof(cp));
2109 bacpy(&cp.bdaddr, &conn->dst);
2110 cp.pscan_rep_mode = 0x02;
2111 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002112 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2113 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002114 conn->dst_type, 0, NULL, 0,
2115 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002116
Johan Hedberg127178d2010-11-18 22:22:29 +02002117 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002118 conn->state = BT_CONNECTED;
2119 hci_proto_connect_cfm(conn, ev->status);
2120 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002121 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002122
Johan Hedbergccd556f2010-11-10 17:11:51 +02002123unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002124 hci_dev_unlock(hdev);
2125}
2126
2127static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2128{
2129 BT_DBG("%s", hdev->name);
2130}
2131
2132static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2133{
2134 BT_DBG("%s", hdev->name);
2135}
2136
2137static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2138{
2139 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2140 __u16 opcode;
2141
2142 skb_pull(skb, sizeof(*ev));
2143
2144 opcode = __le16_to_cpu(ev->opcode);
2145
2146 switch (opcode) {
2147 case HCI_OP_INQUIRY_CANCEL:
2148 hci_cc_inquiry_cancel(hdev, skb);
2149 break;
2150
2151 case HCI_OP_EXIT_PERIODIC_INQ:
2152 hci_cc_exit_periodic_inq(hdev, skb);
2153 break;
2154
2155 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2156 hci_cc_remote_name_req_cancel(hdev, skb);
2157 break;
2158
2159 case HCI_OP_ROLE_DISCOVERY:
2160 hci_cc_role_discovery(hdev, skb);
2161 break;
2162
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002163 case HCI_OP_READ_LINK_POLICY:
2164 hci_cc_read_link_policy(hdev, skb);
2165 break;
2166
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002167 case HCI_OP_WRITE_LINK_POLICY:
2168 hci_cc_write_link_policy(hdev, skb);
2169 break;
2170
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002171 case HCI_OP_READ_DEF_LINK_POLICY:
2172 hci_cc_read_def_link_policy(hdev, skb);
2173 break;
2174
2175 case HCI_OP_WRITE_DEF_LINK_POLICY:
2176 hci_cc_write_def_link_policy(hdev, skb);
2177 break;
2178
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002179 case HCI_OP_RESET:
2180 hci_cc_reset(hdev, skb);
2181 break;
2182
2183 case HCI_OP_WRITE_LOCAL_NAME:
2184 hci_cc_write_local_name(hdev, skb);
2185 break;
2186
2187 case HCI_OP_READ_LOCAL_NAME:
2188 hci_cc_read_local_name(hdev, skb);
2189 break;
2190
2191 case HCI_OP_WRITE_AUTH_ENABLE:
2192 hci_cc_write_auth_enable(hdev, skb);
2193 break;
2194
2195 case HCI_OP_WRITE_ENCRYPT_MODE:
2196 hci_cc_write_encrypt_mode(hdev, skb);
2197 break;
2198
2199 case HCI_OP_WRITE_SCAN_ENABLE:
2200 hci_cc_write_scan_enable(hdev, skb);
2201 break;
2202
2203 case HCI_OP_READ_CLASS_OF_DEV:
2204 hci_cc_read_class_of_dev(hdev, skb);
2205 break;
2206
2207 case HCI_OP_WRITE_CLASS_OF_DEV:
2208 hci_cc_write_class_of_dev(hdev, skb);
2209 break;
2210
2211 case HCI_OP_READ_VOICE_SETTING:
2212 hci_cc_read_voice_setting(hdev, skb);
2213 break;
2214
2215 case HCI_OP_WRITE_VOICE_SETTING:
2216 hci_cc_write_voice_setting(hdev, skb);
2217 break;
2218
2219 case HCI_OP_HOST_BUFFER_SIZE:
2220 hci_cc_host_buffer_size(hdev, skb);
2221 break;
2222
Marcel Holtmann333140b2008-07-14 20:13:48 +02002223 case HCI_OP_WRITE_SSP_MODE:
2224 hci_cc_write_ssp_mode(hdev, skb);
2225 break;
2226
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002227 case HCI_OP_READ_LOCAL_VERSION:
2228 hci_cc_read_local_version(hdev, skb);
2229 break;
2230
2231 case HCI_OP_READ_LOCAL_COMMANDS:
2232 hci_cc_read_local_commands(hdev, skb);
2233 break;
2234
2235 case HCI_OP_READ_LOCAL_FEATURES:
2236 hci_cc_read_local_features(hdev, skb);
2237 break;
2238
Andre Guedes971e3a42011-06-30 19:20:52 -03002239 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2240 hci_cc_read_local_ext_features(hdev, skb);
2241 break;
2242
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002243 case HCI_OP_READ_BUFFER_SIZE:
2244 hci_cc_read_buffer_size(hdev, skb);
2245 break;
2246
2247 case HCI_OP_READ_BD_ADDR:
2248 hci_cc_read_bd_addr(hdev, skb);
2249 break;
2250
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002251 case HCI_OP_READ_DATA_BLOCK_SIZE:
2252 hci_cc_read_data_block_size(hdev, skb);
2253 break;
2254
Johan Hedberg23bb5762010-12-21 23:01:27 +02002255 case HCI_OP_WRITE_CA_TIMEOUT:
2256 hci_cc_write_ca_timeout(hdev, skb);
2257 break;
2258
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002259 case HCI_OP_READ_FLOW_CONTROL_MODE:
2260 hci_cc_read_flow_control_mode(hdev, skb);
2261 break;
2262
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002263 case HCI_OP_READ_LOCAL_AMP_INFO:
2264 hci_cc_read_local_amp_info(hdev, skb);
2265 break;
2266
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002267 case HCI_OP_DELETE_STORED_LINK_KEY:
2268 hci_cc_delete_stored_link_key(hdev, skb);
2269 break;
2270
Johan Hedbergd5859e22011-01-25 01:19:58 +02002271 case HCI_OP_SET_EVENT_MASK:
2272 hci_cc_set_event_mask(hdev, skb);
2273 break;
2274
2275 case HCI_OP_WRITE_INQUIRY_MODE:
2276 hci_cc_write_inquiry_mode(hdev, skb);
2277 break;
2278
2279 case HCI_OP_READ_INQ_RSP_TX_POWER:
2280 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2281 break;
2282
2283 case HCI_OP_SET_EVENT_FLT:
2284 hci_cc_set_event_flt(hdev, skb);
2285 break;
2286
Johan Hedberg980e1a52011-01-22 06:10:07 +02002287 case HCI_OP_PIN_CODE_REPLY:
2288 hci_cc_pin_code_reply(hdev, skb);
2289 break;
2290
2291 case HCI_OP_PIN_CODE_NEG_REPLY:
2292 hci_cc_pin_code_neg_reply(hdev, skb);
2293 break;
2294
Szymon Jancc35938b2011-03-22 13:12:21 +01002295 case HCI_OP_READ_LOCAL_OOB_DATA:
2296 hci_cc_read_local_oob_data_reply(hdev, skb);
2297 break;
2298
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002299 case HCI_OP_LE_READ_BUFFER_SIZE:
2300 hci_cc_le_read_buffer_size(hdev, skb);
2301 break;
2302
Johan Hedberga5c29682011-02-19 12:05:57 -03002303 case HCI_OP_USER_CONFIRM_REPLY:
2304 hci_cc_user_confirm_reply(hdev, skb);
2305 break;
2306
2307 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2308 hci_cc_user_confirm_neg_reply(hdev, skb);
2309 break;
2310
Brian Gix1143d452011-11-23 08:28:34 -08002311 case HCI_OP_USER_PASSKEY_REPLY:
2312 hci_cc_user_passkey_reply(hdev, skb);
2313 break;
2314
2315 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2316 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002317 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002318
2319 case HCI_OP_LE_SET_SCAN_PARAM:
2320 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002321 break;
2322
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002323 case HCI_OP_LE_SET_SCAN_ENABLE:
2324 hci_cc_le_set_scan_enable(hdev, skb);
2325 break;
2326
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002327 case HCI_OP_LE_LTK_REPLY:
2328 hci_cc_le_ltk_reply(hdev, skb);
2329 break;
2330
2331 case HCI_OP_LE_LTK_NEG_REPLY:
2332 hci_cc_le_ltk_neg_reply(hdev, skb);
2333 break;
2334
Andre Guedesf9b49302011-06-30 19:20:53 -03002335 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2336 hci_cc_write_le_host_supported(hdev, skb);
2337 break;
2338
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002339 default:
2340 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2341 break;
2342 }
2343
Ville Tervo6bd32322011-02-16 16:32:41 +02002344 if (ev->opcode != HCI_OP_NOP)
2345 del_timer(&hdev->cmd_timer);
2346
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002347 if (ev->ncmd) {
2348 atomic_set(&hdev->cmd_cnt, 1);
2349 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002350 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002351 }
2352}
2353
2354static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2355{
2356 struct hci_ev_cmd_status *ev = (void *) skb->data;
2357 __u16 opcode;
2358
2359 skb_pull(skb, sizeof(*ev));
2360
2361 opcode = __le16_to_cpu(ev->opcode);
2362
2363 switch (opcode) {
2364 case HCI_OP_INQUIRY:
2365 hci_cs_inquiry(hdev, ev->status);
2366 break;
2367
2368 case HCI_OP_CREATE_CONN:
2369 hci_cs_create_conn(hdev, ev->status);
2370 break;
2371
2372 case HCI_OP_ADD_SCO:
2373 hci_cs_add_sco(hdev, ev->status);
2374 break;
2375
Marcel Holtmannf8558552008-07-14 20:13:49 +02002376 case HCI_OP_AUTH_REQUESTED:
2377 hci_cs_auth_requested(hdev, ev->status);
2378 break;
2379
2380 case HCI_OP_SET_CONN_ENCRYPT:
2381 hci_cs_set_conn_encrypt(hdev, ev->status);
2382 break;
2383
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002384 case HCI_OP_REMOTE_NAME_REQ:
2385 hci_cs_remote_name_req(hdev, ev->status);
2386 break;
2387
Marcel Holtmann769be972008-07-14 20:13:49 +02002388 case HCI_OP_READ_REMOTE_FEATURES:
2389 hci_cs_read_remote_features(hdev, ev->status);
2390 break;
2391
2392 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2393 hci_cs_read_remote_ext_features(hdev, ev->status);
2394 break;
2395
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002396 case HCI_OP_SETUP_SYNC_CONN:
2397 hci_cs_setup_sync_conn(hdev, ev->status);
2398 break;
2399
2400 case HCI_OP_SNIFF_MODE:
2401 hci_cs_sniff_mode(hdev, ev->status);
2402 break;
2403
2404 case HCI_OP_EXIT_SNIFF_MODE:
2405 hci_cs_exit_sniff_mode(hdev, ev->status);
2406 break;
2407
Johan Hedberg8962ee72011-01-20 12:40:27 +02002408 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002409 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002410 break;
2411
Ville Tervofcd89c02011-02-10 22:38:47 -03002412 case HCI_OP_LE_CREATE_CONN:
2413 hci_cs_le_create_conn(hdev, ev->status);
2414 break;
2415
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002416 case HCI_OP_LE_START_ENC:
2417 hci_cs_le_start_enc(hdev, ev->status);
2418 break;
2419
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002420 default:
2421 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2422 break;
2423 }
2424
Ville Tervo6bd32322011-02-16 16:32:41 +02002425 if (ev->opcode != HCI_OP_NOP)
2426 del_timer(&hdev->cmd_timer);
2427
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002428 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002429 atomic_set(&hdev->cmd_cnt, 1);
2430 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002431 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002432 }
2433}
2434
2435static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2436{
2437 struct hci_ev_role_change *ev = (void *) skb->data;
2438 struct hci_conn *conn;
2439
2440 BT_DBG("%s status %d", hdev->name, ev->status);
2441
2442 hci_dev_lock(hdev);
2443
2444 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2445 if (conn) {
2446 if (!ev->status) {
2447 if (ev->role)
2448 conn->link_mode &= ~HCI_LM_MASTER;
2449 else
2450 conn->link_mode |= HCI_LM_MASTER;
2451 }
2452
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002453 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002454
2455 hci_role_switch_cfm(conn, ev->status, ev->role);
2456 }
2457
2458 hci_dev_unlock(hdev);
2459}
2460
Linus Torvalds1da177e2005-04-16 15:20:36 -07002461static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2462{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002463 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002464 int i;
2465
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002466 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2467 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2468 return;
2469 }
2470
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002471 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2472 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473 BT_DBG("%s bad parameters", hdev->name);
2474 return;
2475 }
2476
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002477 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2478
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002479 for (i = 0; i < ev->num_hndl; i++) {
2480 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002481 struct hci_conn *conn;
2482 __u16 handle, count;
2483
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002484 handle = __le16_to_cpu(info->handle);
2485 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486
2487 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002488 if (!conn)
2489 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002490
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002491 conn->sent -= count;
2492
2493 switch (conn->type) {
2494 case ACL_LINK:
2495 hdev->acl_cnt += count;
2496 if (hdev->acl_cnt > hdev->acl_pkts)
2497 hdev->acl_cnt = hdev->acl_pkts;
2498 break;
2499
2500 case LE_LINK:
2501 if (hdev->le_pkts) {
2502 hdev->le_cnt += count;
2503 if (hdev->le_cnt > hdev->le_pkts)
2504 hdev->le_cnt = hdev->le_pkts;
2505 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002506 hdev->acl_cnt += count;
2507 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508 hdev->acl_cnt = hdev->acl_pkts;
2509 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002510 break;
2511
2512 case SCO_LINK:
2513 hdev->sco_cnt += count;
2514 if (hdev->sco_cnt > hdev->sco_pkts)
2515 hdev->sco_cnt = hdev->sco_pkts;
2516 break;
2517
2518 default:
2519 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2520 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002521 }
2522 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002523
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002524 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525}
2526
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002527static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002528 struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002529{
2530 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2531 int i;
2532
2533 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2534 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2535 return;
2536 }
2537
2538 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2539 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2540 BT_DBG("%s bad parameters", hdev->name);
2541 return;
2542 }
2543
2544 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2545 ev->num_hndl);
2546
2547 for (i = 0; i < ev->num_hndl; i++) {
2548 struct hci_comp_blocks_info *info = &ev->handles[i];
2549 struct hci_conn *conn;
2550 __u16 handle, block_count;
2551
2552 handle = __le16_to_cpu(info->handle);
2553 block_count = __le16_to_cpu(info->blocks);
2554
2555 conn = hci_conn_hash_lookup_handle(hdev, handle);
2556 if (!conn)
2557 continue;
2558
2559 conn->sent -= block_count;
2560
2561 switch (conn->type) {
2562 case ACL_LINK:
2563 hdev->block_cnt += block_count;
2564 if (hdev->block_cnt > hdev->num_blocks)
2565 hdev->block_cnt = hdev->num_blocks;
2566 break;
2567
2568 default:
2569 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2570 break;
2571 }
2572 }
2573
2574 queue_work(hdev->workqueue, &hdev->tx_work);
2575}
2576
Marcel Holtmann04837f62006-07-03 10:02:33 +02002577static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002579 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002580 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002581
2582 BT_DBG("%s status %d", hdev->name, ev->status);
2583
2584 hci_dev_lock(hdev);
2585
Marcel Holtmann04837f62006-07-03 10:02:33 +02002586 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2587 if (conn) {
2588 conn->mode = ev->mode;
2589 conn->interval = __le16_to_cpu(ev->interval);
2590
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002591 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002592 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002593 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002594 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002595 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002596 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002597
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002598 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002599 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002600 }
2601
2602 hci_dev_unlock(hdev);
2603}
2604
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2606{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002607 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2608 struct hci_conn *conn;
2609
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002610 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002611
2612 hci_dev_lock(hdev);
2613
2614 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002615 if (!conn)
2616 goto unlock;
2617
2618 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002619 hci_conn_hold(conn);
2620 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2621 hci_conn_put(conn);
2622 }
2623
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002624 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002625 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2626 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002627 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002628 u8 secure;
2629
2630 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2631 secure = 1;
2632 else
2633 secure = 0;
2634
Johan Hedberg744cf192011-11-08 20:40:14 +02002635 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002636 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002637
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002638unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002639 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640}
2641
Linus Torvalds1da177e2005-04-16 15:20:36 -07002642static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2643{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002644 struct hci_ev_link_key_req *ev = (void *) skb->data;
2645 struct hci_cp_link_key_reply cp;
2646 struct hci_conn *conn;
2647 struct link_key *key;
2648
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002649 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002650
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002651 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002652 return;
2653
2654 hci_dev_lock(hdev);
2655
2656 key = hci_find_link_key(hdev, &ev->bdaddr);
2657 if (!key) {
2658 BT_DBG("%s link key not found for %s", hdev->name,
2659 batostr(&ev->bdaddr));
2660 goto not_found;
2661 }
2662
2663 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2664 batostr(&ev->bdaddr));
2665
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002666 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002667 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002668 BT_DBG("%s ignoring debug key", hdev->name);
2669 goto not_found;
2670 }
2671
2672 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002673 if (conn) {
2674 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2675 conn->auth_type != 0xff &&
2676 (conn->auth_type & 0x01)) {
2677 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2678 goto not_found;
2679 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002680
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002681 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2682 conn->pending_sec_level == BT_SECURITY_HIGH) {
2683 BT_DBG("%s ignoring key unauthenticated for high \
2684 security", hdev->name);
2685 goto not_found;
2686 }
2687
2688 conn->key_type = key->type;
2689 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002690 }
2691
2692 bacpy(&cp.bdaddr, &ev->bdaddr);
2693 memcpy(cp.link_key, key->val, 16);
2694
2695 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2696
2697 hci_dev_unlock(hdev);
2698
2699 return;
2700
2701not_found:
2702 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2703 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704}
2705
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2707{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002708 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2709 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002710 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002711
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002712 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002713
2714 hci_dev_lock(hdev);
2715
2716 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2717 if (conn) {
2718 hci_conn_hold(conn);
2719 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002720 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002721
2722 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2723 conn->key_type = ev->key_type;
2724
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002725 hci_conn_put(conn);
2726 }
2727
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002728 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002729 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002730 ev->key_type, pin_len);
2731
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002732 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002733}
2734
Marcel Holtmann04837f62006-07-03 10:02:33 +02002735static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2736{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002737 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002738 struct hci_conn *conn;
2739
2740 BT_DBG("%s status %d", hdev->name, ev->status);
2741
2742 hci_dev_lock(hdev);
2743
2744 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745 if (conn && !ev->status) {
2746 struct inquiry_entry *ie;
2747
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002748 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2749 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750 ie->data.clock_offset = ev->clock_offset;
2751 ie->timestamp = jiffies;
2752 }
2753 }
2754
2755 hci_dev_unlock(hdev);
2756}
2757
Marcel Holtmanna8746412008-07-14 20:13:46 +02002758static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2759{
2760 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2761 struct hci_conn *conn;
2762
2763 BT_DBG("%s status %d", hdev->name, ev->status);
2764
2765 hci_dev_lock(hdev);
2766
2767 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2768 if (conn && !ev->status)
2769 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2770
2771 hci_dev_unlock(hdev);
2772}
2773
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002774static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2775{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002776 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002777 struct inquiry_entry *ie;
2778
2779 BT_DBG("%s", hdev->name);
2780
2781 hci_dev_lock(hdev);
2782
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002783 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2784 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002785 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2786 ie->timestamp = jiffies;
2787 }
2788
2789 hci_dev_unlock(hdev);
2790}
2791
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002792static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2793{
2794 struct inquiry_data data;
2795 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002796 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002797
2798 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2799
2800 if (!num_rsp)
2801 return;
2802
2803 hci_dev_lock(hdev);
2804
2805 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002806 struct inquiry_info_with_rssi_and_pscan_mode *info;
2807 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002808
Johan Hedberge17acd42011-03-30 23:57:16 +03002809 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002810 bacpy(&data.bdaddr, &info->bdaddr);
2811 data.pscan_rep_mode = info->pscan_rep_mode;
2812 data.pscan_period_mode = info->pscan_period_mode;
2813 data.pscan_mode = info->pscan_mode;
2814 memcpy(data.dev_class, info->dev_class, 3);
2815 data.clock_offset = info->clock_offset;
2816 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002817 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002818
2819 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002820 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002821 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002822 info->dev_class, info->rssi,
2823 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002824 }
2825 } else {
2826 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2827
Johan Hedberge17acd42011-03-30 23:57:16 +03002828 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002829 bacpy(&data.bdaddr, &info->bdaddr);
2830 data.pscan_rep_mode = info->pscan_rep_mode;
2831 data.pscan_period_mode = info->pscan_period_mode;
2832 data.pscan_mode = 0x00;
2833 memcpy(data.dev_class, info->dev_class, 3);
2834 data.clock_offset = info->clock_offset;
2835 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002836 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002837 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002838 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002839 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002840 info->dev_class, info->rssi,
2841 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002842 }
2843 }
2844
2845 hci_dev_unlock(hdev);
2846}
2847
2848static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2849{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002850 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2851 struct hci_conn *conn;
2852
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002853 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002854
Marcel Holtmann41a96212008-07-14 20:13:48 +02002855 hci_dev_lock(hdev);
2856
2857 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002858 if (!conn)
2859 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002860
Johan Hedbergccd556f2010-11-10 17:11:51 +02002861 if (!ev->status && ev->page == 0x01) {
2862 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002863
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002864 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2865 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002866 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002867
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002868 if (ev->features[0] & LMP_HOST_SSP)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002869 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002870 }
2871
Johan Hedbergccd556f2010-11-10 17:11:51 +02002872 if (conn->state != BT_CONFIG)
2873 goto unlock;
2874
Johan Hedberg127178d2010-11-18 22:22:29 +02002875 if (!ev->status) {
2876 struct hci_cp_remote_name_req cp;
2877 memset(&cp, 0, sizeof(cp));
2878 bacpy(&cp.bdaddr, &conn->dst);
2879 cp.pscan_rep_mode = 0x02;
2880 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002881 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2882 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002883 conn->dst_type, 0, NULL, 0,
2884 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002885
Johan Hedberg127178d2010-11-18 22:22:29 +02002886 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002887 conn->state = BT_CONNECTED;
2888 hci_proto_connect_cfm(conn, ev->status);
2889 hci_conn_put(conn);
2890 }
2891
2892unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002893 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002894}
2895
2896static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2897{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002898 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2899 struct hci_conn *conn;
2900
2901 BT_DBG("%s status %d", hdev->name, ev->status);
2902
2903 hci_dev_lock(hdev);
2904
2905 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002906 if (!conn) {
2907 if (ev->link_type == ESCO_LINK)
2908 goto unlock;
2909
2910 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2911 if (!conn)
2912 goto unlock;
2913
2914 conn->type = SCO_LINK;
2915 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002916
Marcel Holtmann732547f2009-04-19 19:14:14 +02002917 switch (ev->status) {
2918 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002919 conn->handle = __le16_to_cpu(ev->handle);
2920 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002921
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002922 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002923 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002924 break;
2925
Stephen Coe705e5712010-02-16 11:29:44 -05002926 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002927 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002928 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002929 case 0x1f: /* Unspecified error */
2930 if (conn->out && conn->attempt < 2) {
2931 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2932 (hdev->esco_type & EDR_ESCO_MASK);
2933 hci_setup_sync(conn, conn->link->handle);
2934 goto unlock;
2935 }
2936 /* fall through */
2937
2938 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002939 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002940 break;
2941 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002942
2943 hci_proto_connect_cfm(conn, ev->status);
2944 if (ev->status)
2945 hci_conn_del(conn);
2946
2947unlock:
2948 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002949}
2950
2951static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2952{
2953 BT_DBG("%s", hdev->name);
2954}
2955
Marcel Holtmann04837f62006-07-03 10:02:33 +02002956static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2957{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002958 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002959
2960 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002961}
2962
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002963static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2964{
2965 struct inquiry_data data;
2966 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2967 int num_rsp = *((__u8 *) skb->data);
2968
2969 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2970
2971 if (!num_rsp)
2972 return;
2973
2974 hci_dev_lock(hdev);
2975
Johan Hedberge17acd42011-03-30 23:57:16 +03002976 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002977 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002978
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002979 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002980 data.pscan_rep_mode = info->pscan_rep_mode;
2981 data.pscan_period_mode = info->pscan_period_mode;
2982 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002983 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002984 data.clock_offset = info->clock_offset;
2985 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002986 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002987
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002988 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002989 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002990 sizeof(info->data),
2991 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002992 else
2993 name_known = true;
2994
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002995 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002996 &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002997 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002998 info->dev_class, info->rssi, !name_known,
2999 ssp, info->data, sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003000 }
3001
3002 hci_dev_unlock(hdev);
3003}
3004
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003005static inline u8 hci_get_auth_req(struct hci_conn *conn)
3006{
3007 /* If remote requests dedicated bonding follow that lead */
3008 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3009 /* If both remote and local IO capabilities allow MITM
3010 * protection then require it, otherwise don't */
3011 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3012 return 0x02;
3013 else
3014 return 0x03;
3015 }
3016
3017 /* If remote requests no-bonding follow that lead */
3018 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003019 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003020
3021 return conn->auth_type;
3022}
3023
Marcel Holtmann04936842008-07-14 20:13:48 +02003024static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3025{
3026 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3027 struct hci_conn *conn;
3028
3029 BT_DBG("%s", hdev->name);
3030
3031 hci_dev_lock(hdev);
3032
3033 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003034 if (!conn)
3035 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003036
Johan Hedberg03b555e2011-01-04 15:40:05 +02003037 hci_conn_hold(conn);
3038
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003039 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003040 goto unlock;
3041
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003042 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003043 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003044 struct hci_cp_io_capability_reply cp;
3045
3046 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303047 /* Change the IO capability from KeyboardDisplay
3048 * to DisplayYesNo as it is not supported by BT spec. */
3049 cp.capability = (conn->io_capability == 0x04) ?
3050 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003051 conn->auth_type = hci_get_auth_req(conn);
3052 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003053
Johan Hedberg58a681e2012-01-16 06:47:28 +02003054 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003055 hci_find_remote_oob_data(hdev, &conn->dst))
3056 cp.oob_data = 0x01;
3057 else
3058 cp.oob_data = 0x00;
3059
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003060 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3061 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003062 } else {
3063 struct hci_cp_io_capability_neg_reply cp;
3064
3065 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003066 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003067
3068 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3069 sizeof(cp), &cp);
3070 }
3071
3072unlock:
3073 hci_dev_unlock(hdev);
3074}
3075
3076static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3077{
3078 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3079 struct hci_conn *conn;
3080
3081 BT_DBG("%s", hdev->name);
3082
3083 hci_dev_lock(hdev);
3084
3085 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3086 if (!conn)
3087 goto unlock;
3088
Johan Hedberg03b555e2011-01-04 15:40:05 +02003089 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003090 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003091 if (ev->oob_data)
3092 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003093
3094unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003095 hci_dev_unlock(hdev);
3096}
3097
Johan Hedberga5c29682011-02-19 12:05:57 -03003098static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3099 struct sk_buff *skb)
3100{
3101 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003102 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003103 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003104
3105 BT_DBG("%s", hdev->name);
3106
3107 hci_dev_lock(hdev);
3108
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003109 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003110 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003111
Johan Hedberg7a828902011-04-28 11:28:53 -07003112 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3113 if (!conn)
3114 goto unlock;
3115
3116 loc_mitm = (conn->auth_type & 0x01);
3117 rem_mitm = (conn->remote_auth & 0x01);
3118
3119 /* If we require MITM but the remote device can't provide that
3120 * (it has NoInputNoOutput) then reject the confirmation
3121 * request. The only exception is when we're dedicated bonding
3122 * initiators (connect_cfm_cb set) since then we always have the MITM
3123 * bit set. */
3124 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3125 BT_DBG("Rejecting request: remote device can't provide MITM");
3126 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3127 sizeof(ev->bdaddr), &ev->bdaddr);
3128 goto unlock;
3129 }
3130
3131 /* If no side requires MITM protection; auto-accept */
3132 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3133 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003134
3135 /* If we're not the initiators request authorization to
3136 * proceed from user space (mgmt_user_confirm with
3137 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003138 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003139 BT_DBG("Confirming auto-accept as acceptor");
3140 confirm_hint = 1;
3141 goto confirm;
3142 }
3143
Johan Hedberg9f616562011-04-28 11:28:54 -07003144 BT_DBG("Auto-accept of user confirmation with %ums delay",
3145 hdev->auto_accept_delay);
3146
3147 if (hdev->auto_accept_delay > 0) {
3148 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3149 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3150 goto unlock;
3151 }
3152
Johan Hedberg7a828902011-04-28 11:28:53 -07003153 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3154 sizeof(ev->bdaddr), &ev->bdaddr);
3155 goto unlock;
3156 }
3157
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003158confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003159 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003160 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003161
3162unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003163 hci_dev_unlock(hdev);
3164}
3165
Brian Gix1143d452011-11-23 08:28:34 -08003166static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3167 struct sk_buff *skb)
3168{
3169 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3170
3171 BT_DBG("%s", hdev->name);
3172
3173 hci_dev_lock(hdev);
3174
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003175 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003176 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003177
3178 hci_dev_unlock(hdev);
3179}
3180
Marcel Holtmann04936842008-07-14 20:13:48 +02003181static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3182{
3183 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3184 struct hci_conn *conn;
3185
3186 BT_DBG("%s", hdev->name);
3187
3188 hci_dev_lock(hdev);
3189
3190 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003191 if (!conn)
3192 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003193
Johan Hedberg2a611692011-02-19 12:06:00 -03003194 /* To avoid duplicate auth_failed events to user space we check
3195 * the HCI_CONN_AUTH_PEND flag which will be set if we
3196 * initiated the authentication. A traditional auth_complete
3197 * event gets always produced as initiator and is also mapped to
3198 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003199 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003200 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003201 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003202
3203 hci_conn_put(conn);
3204
3205unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003206 hci_dev_unlock(hdev);
3207}
3208
Marcel Holtmann41a96212008-07-14 20:13:48 +02003209static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3210{
3211 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3212 struct inquiry_entry *ie;
3213
3214 BT_DBG("%s", hdev->name);
3215
3216 hci_dev_lock(hdev);
3217
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003218 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3219 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003220 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003221
3222 hci_dev_unlock(hdev);
3223}
3224
Szymon Janc2763eda2011-03-22 13:12:22 +01003225static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003226 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003227{
3228 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3229 struct oob_data *data;
3230
3231 BT_DBG("%s", hdev->name);
3232
3233 hci_dev_lock(hdev);
3234
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003235 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003236 goto unlock;
3237
Szymon Janc2763eda2011-03-22 13:12:22 +01003238 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3239 if (data) {
3240 struct hci_cp_remote_oob_data_reply cp;
3241
3242 bacpy(&cp.bdaddr, &ev->bdaddr);
3243 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3244 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3245
3246 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3247 &cp);
3248 } else {
3249 struct hci_cp_remote_oob_data_neg_reply cp;
3250
3251 bacpy(&cp.bdaddr, &ev->bdaddr);
3252 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3253 &cp);
3254 }
3255
Szymon Jance1ba1f12011-04-06 13:01:59 +02003256unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003257 hci_dev_unlock(hdev);
3258}
3259
Ville Tervofcd89c02011-02-10 22:38:47 -03003260static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3261{
3262 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3263 struct hci_conn *conn;
3264
3265 BT_DBG("%s status %d", hdev->name, ev->status);
3266
3267 hci_dev_lock(hdev);
3268
3269 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003270 if (!conn) {
3271 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3272 if (!conn) {
3273 BT_ERR("No memory for new connection");
3274 hci_dev_unlock(hdev);
3275 return;
3276 }
Andre Guedes29b79882011-05-31 14:20:54 -03003277
3278 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003279 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003280
3281 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003282 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3283 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003284 hci_proto_connect_cfm(conn, ev->status);
3285 conn->state = BT_CLOSED;
3286 hci_conn_del(conn);
3287 goto unlock;
3288 }
3289
Johan Hedbergb644ba32012-01-17 21:48:47 +02003290 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3291 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003292 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003293
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003294 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003295 conn->handle = __le16_to_cpu(ev->handle);
3296 conn->state = BT_CONNECTED;
3297
3298 hci_conn_hold_device(conn);
3299 hci_conn_add_sysfs(conn);
3300
3301 hci_proto_connect_cfm(conn, ev->status);
3302
3303unlock:
3304 hci_dev_unlock(hdev);
3305}
3306
Andre Guedes9aa04c92011-05-26 16:23:51 -03003307static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3308 struct sk_buff *skb)
3309{
Andre Guedese95beb42011-09-26 20:48:35 -03003310 u8 num_reports = skb->data[0];
3311 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003312 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003313
3314 hci_dev_lock(hdev);
3315
Andre Guedese95beb42011-09-26 20:48:35 -03003316 while (num_reports--) {
3317 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003318
Andre Guedes9aa04c92011-05-26 16:23:51 -03003319 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003320
Andre Guedes3c9e9192012-01-10 18:20:50 -03003321 rssi = ev->data[ev->length];
3322 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003323 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003324
Andre Guedese95beb42011-09-26 20:48:35 -03003325 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003326 }
3327
3328 hci_dev_unlock(hdev);
3329}
3330
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003331static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3332 struct sk_buff *skb)
3333{
3334 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3335 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003336 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003337 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003338 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003339
Andrei Emeltchenkoe4666882012-03-09 11:59:15 +02003340 BT_DBG("%s handle %d", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003341
3342 hci_dev_lock(hdev);
3343
3344 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003345 if (conn == NULL)
3346 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003347
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003348 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3349 if (ltk == NULL)
3350 goto not_found;
3351
3352 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003353 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003354
3355 if (ltk->authenticated)
3356 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003357
3358 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3359
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003360 if (ltk->type & HCI_SMP_STK) {
3361 list_del(&ltk->list);
3362 kfree(ltk);
3363 }
3364
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003365 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003366
3367 return;
3368
3369not_found:
3370 neg.handle = ev->handle;
3371 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3372 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003373}
3374
Ville Tervofcd89c02011-02-10 22:38:47 -03003375static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3376{
3377 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3378
3379 skb_pull(skb, sizeof(*le_ev));
3380
3381 switch (le_ev->subevent) {
3382 case HCI_EV_LE_CONN_COMPLETE:
3383 hci_le_conn_complete_evt(hdev, skb);
3384 break;
3385
Andre Guedes9aa04c92011-05-26 16:23:51 -03003386 case HCI_EV_LE_ADVERTISING_REPORT:
3387 hci_le_adv_report_evt(hdev, skb);
3388 break;
3389
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003390 case HCI_EV_LE_LTK_REQ:
3391 hci_le_ltk_request_evt(hdev, skb);
3392 break;
3393
Ville Tervofcd89c02011-02-10 22:38:47 -03003394 default:
3395 break;
3396 }
3397}
3398
Linus Torvalds1da177e2005-04-16 15:20:36 -07003399void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3400{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003401 struct hci_event_hdr *hdr = (void *) skb->data;
3402 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403
3404 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3405
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003406 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003407 case HCI_EV_INQUIRY_COMPLETE:
3408 hci_inquiry_complete_evt(hdev, skb);
3409 break;
3410
3411 case HCI_EV_INQUIRY_RESULT:
3412 hci_inquiry_result_evt(hdev, skb);
3413 break;
3414
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003415 case HCI_EV_CONN_COMPLETE:
3416 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003417 break;
3418
Linus Torvalds1da177e2005-04-16 15:20:36 -07003419 case HCI_EV_CONN_REQUEST:
3420 hci_conn_request_evt(hdev, skb);
3421 break;
3422
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423 case HCI_EV_DISCONN_COMPLETE:
3424 hci_disconn_complete_evt(hdev, skb);
3425 break;
3426
Linus Torvalds1da177e2005-04-16 15:20:36 -07003427 case HCI_EV_AUTH_COMPLETE:
3428 hci_auth_complete_evt(hdev, skb);
3429 break;
3430
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003431 case HCI_EV_REMOTE_NAME:
3432 hci_remote_name_evt(hdev, skb);
3433 break;
3434
Linus Torvalds1da177e2005-04-16 15:20:36 -07003435 case HCI_EV_ENCRYPT_CHANGE:
3436 hci_encrypt_change_evt(hdev, skb);
3437 break;
3438
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003439 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3440 hci_change_link_key_complete_evt(hdev, skb);
3441 break;
3442
3443 case HCI_EV_REMOTE_FEATURES:
3444 hci_remote_features_evt(hdev, skb);
3445 break;
3446
3447 case HCI_EV_REMOTE_VERSION:
3448 hci_remote_version_evt(hdev, skb);
3449 break;
3450
3451 case HCI_EV_QOS_SETUP_COMPLETE:
3452 hci_qos_setup_complete_evt(hdev, skb);
3453 break;
3454
3455 case HCI_EV_CMD_COMPLETE:
3456 hci_cmd_complete_evt(hdev, skb);
3457 break;
3458
3459 case HCI_EV_CMD_STATUS:
3460 hci_cmd_status_evt(hdev, skb);
3461 break;
3462
3463 case HCI_EV_ROLE_CHANGE:
3464 hci_role_change_evt(hdev, skb);
3465 break;
3466
3467 case HCI_EV_NUM_COMP_PKTS:
3468 hci_num_comp_pkts_evt(hdev, skb);
3469 break;
3470
3471 case HCI_EV_MODE_CHANGE:
3472 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003473 break;
3474
3475 case HCI_EV_PIN_CODE_REQ:
3476 hci_pin_code_request_evt(hdev, skb);
3477 break;
3478
3479 case HCI_EV_LINK_KEY_REQ:
3480 hci_link_key_request_evt(hdev, skb);
3481 break;
3482
3483 case HCI_EV_LINK_KEY_NOTIFY:
3484 hci_link_key_notify_evt(hdev, skb);
3485 break;
3486
3487 case HCI_EV_CLOCK_OFFSET:
3488 hci_clock_offset_evt(hdev, skb);
3489 break;
3490
Marcel Holtmanna8746412008-07-14 20:13:46 +02003491 case HCI_EV_PKT_TYPE_CHANGE:
3492 hci_pkt_type_change_evt(hdev, skb);
3493 break;
3494
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003495 case HCI_EV_PSCAN_REP_MODE:
3496 hci_pscan_rep_mode_evt(hdev, skb);
3497 break;
3498
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003499 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3500 hci_inquiry_result_with_rssi_evt(hdev, skb);
3501 break;
3502
3503 case HCI_EV_REMOTE_EXT_FEATURES:
3504 hci_remote_ext_features_evt(hdev, skb);
3505 break;
3506
3507 case HCI_EV_SYNC_CONN_COMPLETE:
3508 hci_sync_conn_complete_evt(hdev, skb);
3509 break;
3510
3511 case HCI_EV_SYNC_CONN_CHANGED:
3512 hci_sync_conn_changed_evt(hdev, skb);
3513 break;
3514
Marcel Holtmann04837f62006-07-03 10:02:33 +02003515 case HCI_EV_SNIFF_SUBRATE:
3516 hci_sniff_subrate_evt(hdev, skb);
3517 break;
3518
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003519 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3520 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003521 break;
3522
Marcel Holtmann04936842008-07-14 20:13:48 +02003523 case HCI_EV_IO_CAPA_REQUEST:
3524 hci_io_capa_request_evt(hdev, skb);
3525 break;
3526
Johan Hedberg03b555e2011-01-04 15:40:05 +02003527 case HCI_EV_IO_CAPA_REPLY:
3528 hci_io_capa_reply_evt(hdev, skb);
3529 break;
3530
Johan Hedberga5c29682011-02-19 12:05:57 -03003531 case HCI_EV_USER_CONFIRM_REQUEST:
3532 hci_user_confirm_request_evt(hdev, skb);
3533 break;
3534
Brian Gix1143d452011-11-23 08:28:34 -08003535 case HCI_EV_USER_PASSKEY_REQUEST:
3536 hci_user_passkey_request_evt(hdev, skb);
3537 break;
3538
Marcel Holtmann04936842008-07-14 20:13:48 +02003539 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3540 hci_simple_pair_complete_evt(hdev, skb);
3541 break;
3542
Marcel Holtmann41a96212008-07-14 20:13:48 +02003543 case HCI_EV_REMOTE_HOST_FEATURES:
3544 hci_remote_host_features_evt(hdev, skb);
3545 break;
3546
Ville Tervofcd89c02011-02-10 22:38:47 -03003547 case HCI_EV_LE_META:
3548 hci_le_meta_evt(hdev, skb);
3549 break;
3550
Szymon Janc2763eda2011-03-22 13:12:22 +01003551 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3552 hci_remote_oob_data_request_evt(hdev, skb);
3553 break;
3554
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003555 case HCI_EV_NUM_COMP_BLOCKS:
3556 hci_num_comp_blocks_evt(hdev, skb);
3557 break;
3558
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003559 default:
3560 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003561 break;
3562 }
3563
3564 kfree_skb(skb);
3565 hdev->stat.evt_rx++;
3566}