blob: 239e9fb8f7c523630ee8354dd6c2f2da4812129d [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
38#include <linux/notifier.h>
39#include <net/sock.h>
40
41#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020042#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <asm/unaligned.h>
44
45#include <net/bluetooth/bluetooth.h>
46#include <net/bluetooth/hci_core.h>
47
Rusty Russelleb939922011-12-19 14:08:01 +000048static bool enable_le;
Andre Guedese6100a22011-06-30 19:20:54 -030049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050/* Handle HCI Event packets */
51
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070053{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020054 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Marcel Holtmanna9de9242007-10-20 13:33:56 +020056 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Andre Guedese6d465c2011-11-09 17:14:26 -030058 if (status) {
59 hci_dev_lock(hdev);
60 mgmt_stop_discovery_failed(hdev, status);
61 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020062 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030063 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Andre Guedes89352e72011-11-04 14:16:53 -030065 clear_bit(HCI_INQUIRY, &hdev->flags);
66
Johan Hedberg56e5cb82011-11-08 20:40:16 +020067 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020068 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020069 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010070
Johan Hedberg23bb5762010-12-21 23:01:27 +020071 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010072
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070074}
75
Marcel Holtmanna9de9242007-10-20 13:33:56 +020076static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070077{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020078 __u8 status = *((__u8 *) skb->data);
79
80 BT_DBG("%s status 0x%x", hdev->name, status);
81
82 if (status)
83 return;
84
Marcel Holtmanna9de9242007-10-20 13:33:56 +020085 hci_conn_check_pending(hdev);
86}
87
88static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
89{
90 BT_DBG("%s", hdev->name);
91}
92
93static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
94{
95 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Marcel Holtmanna9de9242007-10-20 13:33:56 +020098 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 if (rp->status)
101 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200103 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
106 if (conn) {
107 if (rp->role)
108 conn->link_mode &= ~HCI_LM_MASTER;
109 else
110 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200112
113 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114}
115
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200116static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
117{
118 struct hci_rp_read_link_policy *rp = (void *) skb->data;
119 struct hci_conn *conn;
120
121 BT_DBG("%s status 0x%x", hdev->name, rp->status);
122
123 if (rp->status)
124 return;
125
126 hci_dev_lock(hdev);
127
128 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
129 if (conn)
130 conn->link_policy = __le16_to_cpu(rp->policy);
131
132 hci_dev_unlock(hdev);
133}
134
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200137 struct hci_rp_write_link_policy *rp = (void *) skb->data;
138 struct hci_conn *conn;
139 void *sent;
140
141 BT_DBG("%s status 0x%x", hdev->name, rp->status);
142
143 if (rp->status)
144 return;
145
146 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
147 if (!sent)
148 return;
149
150 hci_dev_lock(hdev);
151
152 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200153 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700154 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200155
156 hci_dev_unlock(hdev);
157}
158
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200159static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
160{
161 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
162
163 BT_DBG("%s status 0x%x", hdev->name, rp->status);
164
165 if (rp->status)
166 return;
167
168 hdev->link_policy = __le16_to_cpu(rp->policy);
169}
170
171static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
172{
173 __u8 status = *((__u8 *) skb->data);
174 void *sent;
175
176 BT_DBG("%s status 0x%x", hdev->name, status);
177
178 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
179 if (!sent)
180 return;
181
182 if (!status)
183 hdev->link_policy = get_unaligned_le16(sent);
184
Johan Hedberg23bb5762010-12-21 23:01:27 +0200185 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200186}
187
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200188static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
189{
190 __u8 status = *((__u8 *) skb->data);
191
192 BT_DBG("%s status 0x%x", hdev->name, status);
193
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300194 clear_bit(HCI_RESET, &hdev->flags);
195
Johan Hedberg23bb5762010-12-21 23:01:27 +0200196 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300197
Johan Hedberg7005ff1782012-01-18 16:14:43 +0200198 /* Reset all flags, except persistent ones */
Hemant Gupta95947a32012-01-23 15:36:11 +0530199 hdev->dev_flags &= BIT(HCI_MGMT) | BIT(HCI_SETUP) | BIT(HCI_AUTO_OFF) |
200 BIT(HCI_LINK_KEYS) | BIT(HCI_DEBUG_KEYS);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200201}
202
203static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
204{
205 __u8 status = *((__u8 *) skb->data);
206 void *sent;
207
208 BT_DBG("%s status 0x%x", hdev->name, status);
209
210 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
211 if (!sent)
212 return;
213
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200214 hci_dev_lock(hdev);
215
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200216 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200217 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200218
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200219 if (status == 0)
220 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200221
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200222 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200223}
224
225static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
226{
227 struct hci_rp_read_local_name *rp = (void *) skb->data;
228
229 BT_DBG("%s status 0x%x", hdev->name, rp->status);
230
231 if (rp->status)
232 return;
233
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200234 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200235}
236
237static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
238{
239 __u8 status = *((__u8 *) skb->data);
240 void *sent;
241
242 BT_DBG("%s status 0x%x", hdev->name, status);
243
244 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
245 if (!sent)
246 return;
247
248 if (!status) {
249 __u8 param = *((__u8 *) sent);
250
251 if (param == AUTH_ENABLED)
252 set_bit(HCI_AUTH, &hdev->flags);
253 else
254 clear_bit(HCI_AUTH, &hdev->flags);
255 }
256
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200257 if (test_bit(HCI_MGMT, &hdev->dev_flags))
258 mgmt_auth_enable_complete(hdev, status);
259
Johan Hedberg23bb5762010-12-21 23:01:27 +0200260 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200261}
262
263static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
264{
265 __u8 status = *((__u8 *) skb->data);
266 void *sent;
267
268 BT_DBG("%s status 0x%x", hdev->name, status);
269
270 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
271 if (!sent)
272 return;
273
274 if (!status) {
275 __u8 param = *((__u8 *) sent);
276
277 if (param)
278 set_bit(HCI_ENCRYPT, &hdev->flags);
279 else
280 clear_bit(HCI_ENCRYPT, &hdev->flags);
281 }
282
Johan Hedberg23bb5762010-12-21 23:01:27 +0200283 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200284}
285
286static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
287{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200288 __u8 param, status = *((__u8 *) skb->data);
289 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200290 void *sent;
291
292 BT_DBG("%s status 0x%x", hdev->name, status);
293
294 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
295 if (!sent)
296 return;
297
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200298 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200299
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200300 hci_dev_lock(hdev);
301
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200302 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200303 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200304 hdev->discov_timeout = 0;
305 goto done;
306 }
307
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200308 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
309 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200310
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200311 if (param & SCAN_INQUIRY) {
312 set_bit(HCI_ISCAN, &hdev->flags);
313 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200314 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200315 if (hdev->discov_timeout > 0) {
316 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
317 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
318 to);
319 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200320 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200321 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200322
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 if (param & SCAN_PAGE) {
324 set_bit(HCI_PSCAN, &hdev->flags);
325 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200328 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200329
330done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200331 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200332 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200333}
334
335static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
336{
337 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
338
339 BT_DBG("%s status 0x%x", hdev->name, rp->status);
340
341 if (rp->status)
342 return;
343
344 memcpy(hdev->dev_class, rp->dev_class, 3);
345
346 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
347 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
348}
349
350static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
351{
352 __u8 status = *((__u8 *) skb->data);
353 void *sent;
354
355 BT_DBG("%s status 0x%x", hdev->name, status);
356
Marcel Holtmannf383f272008-07-14 20:13:47 +0200357 if (status)
358 return;
359
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200360 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
361 if (!sent)
362 return;
363
Marcel Holtmannf383f272008-07-14 20:13:47 +0200364 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200365}
366
367static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
368{
369 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200371
372 BT_DBG("%s status 0x%x", hdev->name, rp->status);
373
374 if (rp->status)
375 return;
376
377 setting = __le16_to_cpu(rp->voice_setting);
378
Marcel Holtmannf383f272008-07-14 20:13:47 +0200379 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200380 return;
381
382 hdev->voice_setting = setting;
383
384 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
385
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200386 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200387 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200388}
389
390static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
391{
392 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200393 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 void *sent;
395
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200396 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397
Marcel Holtmannf383f272008-07-14 20:13:47 +0200398 if (status)
399 return;
400
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200401 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
402 if (!sent)
403 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404
Marcel Holtmannf383f272008-07-14 20:13:47 +0200405 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
Marcel Holtmannf383f272008-07-14 20:13:47 +0200407 if (hdev->voice_setting == setting)
408 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Marcel Holtmannf383f272008-07-14 20:13:47 +0200412 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
413
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200414 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200415 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416}
417
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200418static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200420 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200422 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423
Johan Hedberg23bb5762010-12-21 23:01:27 +0200424 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425}
426
Marcel Holtmann333140b2008-07-14 20:13:48 +0200427static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
428{
429 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
430
431 BT_DBG("%s status 0x%x", hdev->name, rp->status);
432
433 if (rp->status)
434 return;
435
Johan Hedberg84bde9d2012-01-25 14:21:06 +0200436 if (rp->mode)
437 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
438 else
439 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200440}
441
442static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
443{
444 __u8 status = *((__u8 *) skb->data);
445 void *sent;
446
447 BT_DBG("%s status 0x%x", hdev->name, status);
448
449 if (status)
450 return;
451
452 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
453 if (!sent)
454 return;
455
Johan Hedberg84bde9d2012-01-25 14:21:06 +0200456 if (*((u8 *) sent))
457 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
458 else
459 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200460}
461
Johan Hedbergd5859e22011-01-25 01:19:58 +0200462static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
463{
464 if (hdev->features[6] & LMP_EXT_INQ)
465 return 2;
466
467 if (hdev->features[3] & LMP_RSSI_INQ)
468 return 1;
469
470 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
471 hdev->lmp_subver == 0x0757)
472 return 1;
473
474 if (hdev->manufacturer == 15) {
475 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
476 return 1;
477 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
478 return 1;
479 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
480 return 1;
481 }
482
483 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
484 hdev->lmp_subver == 0x1805)
485 return 1;
486
487 return 0;
488}
489
490static void hci_setup_inquiry_mode(struct hci_dev *hdev)
491{
492 u8 mode;
493
494 mode = hci_get_inquiry_mode(hdev);
495
496 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
497}
498
499static void hci_setup_event_mask(struct hci_dev *hdev)
500{
501 /* The second byte is 0xff instead of 0x9f (two reserved bits
502 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
503 * command otherwise */
504 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
505
Ville Tervo6de6c182011-05-27 11:16:21 +0300506 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
507 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200508 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300509 return;
510
511 events[4] |= 0x01; /* Flow Specification Complete */
512 events[4] |= 0x02; /* Inquiry Result with RSSI */
513 events[4] |= 0x04; /* Read Remote Extended Features Complete */
514 events[5] |= 0x08; /* Synchronous Connection Complete */
515 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200516
517 if (hdev->features[3] & LMP_RSSI_INQ)
518 events[4] |= 0x04; /* Inquiry Result with RSSI */
519
520 if (hdev->features[5] & LMP_SNIFF_SUBR)
521 events[5] |= 0x20; /* Sniff Subrating */
522
523 if (hdev->features[5] & LMP_PAUSE_ENC)
524 events[5] |= 0x80; /* Encryption Key Refresh Complete */
525
526 if (hdev->features[6] & LMP_EXT_INQ)
527 events[5] |= 0x40; /* Extended Inquiry Result */
528
529 if (hdev->features[6] & LMP_NO_FLUSH)
530 events[7] |= 0x01; /* Enhanced Flush Complete */
531
532 if (hdev->features[7] & LMP_LSTO)
533 events[6] |= 0x80; /* Link Supervision Timeout Changed */
534
535 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
536 events[6] |= 0x01; /* IO Capability Request */
537 events[6] |= 0x02; /* IO Capability Response */
538 events[6] |= 0x04; /* User Confirmation Request */
539 events[6] |= 0x08; /* User Passkey Request */
540 events[6] |= 0x10; /* Remote OOB Data Request */
541 events[6] |= 0x20; /* Simple Pairing Complete */
542 events[7] |= 0x04; /* User Passkey Notification */
543 events[7] |= 0x08; /* Keypress Notification */
544 events[7] |= 0x10; /* Remote Host Supported
545 * Features Notification */
546 }
547
548 if (hdev->features[4] & LMP_LE)
549 events[7] |= 0x20; /* LE Meta-Event */
550
551 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
552}
553
Andre Guedese6100a22011-06-30 19:20:54 -0300554static void hci_set_le_support(struct hci_dev *hdev)
555{
556 struct hci_cp_write_le_host_supported cp;
557
558 memset(&cp, 0, sizeof(cp));
559
560 if (enable_le) {
561 cp.le = 1;
562 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
563 }
564
565 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
566}
567
Johan Hedbergd5859e22011-01-25 01:19:58 +0200568static void hci_setup(struct hci_dev *hdev)
569{
Andrei Emeltchenkoe61ef492011-12-19 16:31:27 +0200570 if (hdev->dev_type != HCI_BREDR)
571 return;
572
Johan Hedbergd5859e22011-01-25 01:19:58 +0200573 hci_setup_event_mask(hdev);
574
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200575 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200576 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
577
578 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
579 u8 mode = 0x01;
580 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
581 }
582
583 if (hdev->features[3] & LMP_RSSI_INQ)
584 hci_setup_inquiry_mode(hdev);
585
586 if (hdev->features[7] & LMP_INQ_TX_PWR)
587 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300588
589 if (hdev->features[7] & LMP_EXTFEATURES) {
590 struct hci_cp_read_local_ext_features cp;
591
592 cp.page = 0x01;
593 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
594 sizeof(cp), &cp);
595 }
Andre Guedese6100a22011-06-30 19:20:54 -0300596
597 if (hdev->features[4] & LMP_LE)
598 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200599}
600
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200601static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
602{
603 struct hci_rp_read_local_version *rp = (void *) skb->data;
604
605 BT_DBG("%s status 0x%x", hdev->name, rp->status);
606
607 if (rp->status)
608 return;
609
610 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200611 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200612 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200613 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200614 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200615
616 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
617 hdev->manufacturer,
618 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200619
620 if (test_bit(HCI_INIT, &hdev->flags))
621 hci_setup(hdev);
622}
623
624static void hci_setup_link_policy(struct hci_dev *hdev)
625{
626 u16 link_policy = 0;
627
628 if (hdev->features[0] & LMP_RSWITCH)
629 link_policy |= HCI_LP_RSWITCH;
630 if (hdev->features[0] & LMP_HOLD)
631 link_policy |= HCI_LP_HOLD;
632 if (hdev->features[0] & LMP_SNIFF)
633 link_policy |= HCI_LP_SNIFF;
634 if (hdev->features[1] & LMP_PARK)
635 link_policy |= HCI_LP_PARK;
636
637 link_policy = cpu_to_le16(link_policy);
638 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
639 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200640}
641
642static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
643{
644 struct hci_rp_read_local_commands *rp = (void *) skb->data;
645
646 BT_DBG("%s status 0x%x", hdev->name, rp->status);
647
648 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200649 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200650
651 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200652
653 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
654 hci_setup_link_policy(hdev);
655
656done:
657 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200658}
659
660static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
661{
662 struct hci_rp_read_local_features *rp = (void *) skb->data;
663
664 BT_DBG("%s status 0x%x", hdev->name, rp->status);
665
666 if (rp->status)
667 return;
668
669 memcpy(hdev->features, rp->features, 8);
670
671 /* Adjust default settings according to features
672 * supported by device. */
673
674 if (hdev->features[0] & LMP_3SLOT)
675 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
676
677 if (hdev->features[0] & LMP_5SLOT)
678 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
679
680 if (hdev->features[1] & LMP_HV2) {
681 hdev->pkt_type |= (HCI_HV2);
682 hdev->esco_type |= (ESCO_HV2);
683 }
684
685 if (hdev->features[1] & LMP_HV3) {
686 hdev->pkt_type |= (HCI_HV3);
687 hdev->esco_type |= (ESCO_HV3);
688 }
689
690 if (hdev->features[3] & LMP_ESCO)
691 hdev->esco_type |= (ESCO_EV3);
692
693 if (hdev->features[4] & LMP_EV4)
694 hdev->esco_type |= (ESCO_EV4);
695
696 if (hdev->features[4] & LMP_EV5)
697 hdev->esco_type |= (ESCO_EV5);
698
Marcel Holtmannefc76882009-02-06 09:13:37 +0100699 if (hdev->features[5] & LMP_EDR_ESCO_2M)
700 hdev->esco_type |= (ESCO_2EV3);
701
702 if (hdev->features[5] & LMP_EDR_ESCO_3M)
703 hdev->esco_type |= (ESCO_3EV3);
704
705 if (hdev->features[5] & LMP_EDR_3S_ESCO)
706 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
707
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200708 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
709 hdev->features[0], hdev->features[1],
710 hdev->features[2], hdev->features[3],
711 hdev->features[4], hdev->features[5],
712 hdev->features[6], hdev->features[7]);
713}
714
Andre Guedes971e3a42011-06-30 19:20:52 -0300715static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
716 struct sk_buff *skb)
717{
718 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
719
720 BT_DBG("%s status 0x%x", hdev->name, rp->status);
721
722 if (rp->status)
723 return;
724
Andre Guedesb5b32b62011-12-30 10:34:04 -0300725 switch (rp->page) {
726 case 0:
727 memcpy(hdev->features, rp->features, 8);
728 break;
729 case 1:
730 memcpy(hdev->host_features, rp->features, 8);
731 break;
732 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300733
734 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
735}
736
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200737static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
738 struct sk_buff *skb)
739{
740 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
741
742 BT_DBG("%s status 0x%x", hdev->name, rp->status);
743
744 if (rp->status)
745 return;
746
747 hdev->flow_ctl_mode = rp->mode;
748
749 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
750}
751
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200752static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
753{
754 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
755
756 BT_DBG("%s status 0x%x", hdev->name, rp->status);
757
758 if (rp->status)
759 return;
760
761 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
762 hdev->sco_mtu = rp->sco_mtu;
763 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
764 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
765
766 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
767 hdev->sco_mtu = 64;
768 hdev->sco_pkts = 8;
769 }
770
771 hdev->acl_cnt = hdev->acl_pkts;
772 hdev->sco_cnt = hdev->sco_pkts;
773
774 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
775 hdev->acl_mtu, hdev->acl_pkts,
776 hdev->sco_mtu, hdev->sco_pkts);
777}
778
779static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
780{
781 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
782
783 BT_DBG("%s status 0x%x", hdev->name, rp->status);
784
785 if (!rp->status)
786 bacpy(&hdev->bdaddr, &rp->bdaddr);
787
Johan Hedberg23bb5762010-12-21 23:01:27 +0200788 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
789}
790
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200791static void hci_cc_read_data_block_size(struct hci_dev *hdev,
792 struct sk_buff *skb)
793{
794 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
795
796 BT_DBG("%s status 0x%x", hdev->name, rp->status);
797
798 if (rp->status)
799 return;
800
801 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
802 hdev->block_len = __le16_to_cpu(rp->block_len);
803 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
804
805 hdev->block_cnt = hdev->num_blocks;
806
807 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
808 hdev->block_cnt, hdev->block_len);
809
810 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
811}
812
Johan Hedberg23bb5762010-12-21 23:01:27 +0200813static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
814{
815 __u8 status = *((__u8 *) skb->data);
816
817 BT_DBG("%s status 0x%x", hdev->name, status);
818
819 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200820}
821
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300822static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
823 struct sk_buff *skb)
824{
825 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
826
827 BT_DBG("%s status 0x%x", hdev->name, rp->status);
828
829 if (rp->status)
830 return;
831
832 hdev->amp_status = rp->amp_status;
833 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
834 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
835 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
836 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
837 hdev->amp_type = rp->amp_type;
838 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
839 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
840 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
841 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
842
843 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
844}
845
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200846static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
847 struct sk_buff *skb)
848{
849 __u8 status = *((__u8 *) skb->data);
850
851 BT_DBG("%s status 0x%x", hdev->name, status);
852
853 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
854}
855
Johan Hedbergd5859e22011-01-25 01:19:58 +0200856static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
857{
858 __u8 status = *((__u8 *) skb->data);
859
860 BT_DBG("%s status 0x%x", hdev->name, status);
861
862 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
863}
864
865static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
866 struct sk_buff *skb)
867{
868 __u8 status = *((__u8 *) skb->data);
869
870 BT_DBG("%s status 0x%x", hdev->name, status);
871
872 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
873}
874
875static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
876 struct sk_buff *skb)
877{
878 __u8 status = *((__u8 *) skb->data);
879
880 BT_DBG("%s status 0x%x", hdev->name, status);
881
882 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
883}
884
885static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
886{
887 __u8 status = *((__u8 *) skb->data);
888
889 BT_DBG("%s status 0x%x", hdev->name, status);
890
891 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
892}
893
Johan Hedberg980e1a52011-01-22 06:10:07 +0200894static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
895{
896 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
897 struct hci_cp_pin_code_reply *cp;
898 struct hci_conn *conn;
899
900 BT_DBG("%s status 0x%x", hdev->name, rp->status);
901
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200902 hci_dev_lock(hdev);
903
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200904 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200905 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200906
907 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200908 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200909
910 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
911 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200912 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200913
914 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
915 if (conn)
916 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200917
918unlock:
919 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200920}
921
922static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
923{
924 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
925
926 BT_DBG("%s status 0x%x", hdev->name, rp->status);
927
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200928 hci_dev_lock(hdev);
929
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200930 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200931 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200932 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200933
934 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200935}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200936
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300937static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
938 struct sk_buff *skb)
939{
940 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
941
942 BT_DBG("%s status 0x%x", hdev->name, rp->status);
943
944 if (rp->status)
945 return;
946
947 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
948 hdev->le_pkts = rp->le_max_pkt;
949
950 hdev->le_cnt = hdev->le_pkts;
951
952 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
953
954 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
955}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200956
Johan Hedberga5c29682011-02-19 12:05:57 -0300957static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
958{
959 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
960
961 BT_DBG("%s status 0x%x", hdev->name, rp->status);
962
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200963 hci_dev_lock(hdev);
964
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200965 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200966 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
967 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200968
969 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300970}
971
972static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
973 struct sk_buff *skb)
974{
975 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
976
977 BT_DBG("%s status 0x%x", hdev->name, rp->status);
978
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200979 hci_dev_lock(hdev);
980
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200981 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200982 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200983 ACL_LINK, 0,
Johan Hedberga5c29682011-02-19 12:05:57 -0300984 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200985
986 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300987}
988
Brian Gix1143d452011-11-23 08:28:34 -0800989static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
990{
991 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
992
993 BT_DBG("%s status 0x%x", hdev->name, rp->status);
994
995 hci_dev_lock(hdev);
996
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200997 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200998 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
999 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001000
1001 hci_dev_unlock(hdev);
1002}
1003
1004static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1005 struct sk_buff *skb)
1006{
1007 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1008
1009 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1010
1011 hci_dev_lock(hdev);
1012
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001013 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001014 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001015 ACL_LINK, 0,
Brian Gix1143d452011-11-23 08:28:34 -08001016 rp->status);
1017
1018 hci_dev_unlock(hdev);
1019}
1020
Szymon Jancc35938b2011-03-22 13:12:21 +01001021static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1022 struct sk_buff *skb)
1023{
1024 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1025
1026 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1027
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001028 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001029 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001030 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001031 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001032}
1033
Andre Guedes07f7fa52011-12-02 21:13:31 +09001034static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1035{
1036 __u8 status = *((__u8 *) skb->data);
1037
1038 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001039
1040 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001041
1042 if (status) {
1043 hci_dev_lock(hdev);
1044 mgmt_start_discovery_failed(hdev, status);
1045 hci_dev_unlock(hdev);
1046 return;
1047 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001048}
1049
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001050static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1051 struct sk_buff *skb)
1052{
1053 struct hci_cp_le_set_scan_enable *cp;
1054 __u8 status = *((__u8 *) skb->data);
1055
1056 BT_DBG("%s status 0x%x", hdev->name, status);
1057
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001058 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1059 if (!cp)
1060 return;
1061
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001062 switch (cp->enable) {
1063 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001064 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1065
Andre Guedes3fd24152012-02-03 17:48:01 -03001066 if (status) {
1067 hci_dev_lock(hdev);
1068 mgmt_start_discovery_failed(hdev, status);
1069 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001070 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001071 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001072
Andre Guedesd23264a2011-11-25 20:53:38 -03001073 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1074
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001075 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001076
1077 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001078 hci_adv_entries_clear(hdev);
Andre Guedesc5990082012-02-03 17:47:57 -03001079 hci_discovery_set_state(hdev, DISCOVERY_LE_SCAN);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001080 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001081 break;
1082
1083 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001084 if (status)
1085 return;
1086
Andre Guedesd23264a2011-11-25 20:53:38 -03001087 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1088
Andre Guedesc5990082012-02-03 17:47:57 -03001089 hci_dev_lock(hdev);
1090 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1091 hci_dev_unlock(hdev);
1092
Andre Guedesd0843292012-01-02 19:18:11 -03001093 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001094 break;
1095
1096 default:
1097 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1098 break;
Andre Guedes35815082011-05-26 16:23:53 -03001099 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001100}
1101
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001102static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1103{
1104 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1105
1106 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1107
1108 if (rp->status)
1109 return;
1110
1111 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1112}
1113
1114static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1115{
1116 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1117
1118 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1119
1120 if (rp->status)
1121 return;
1122
1123 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1124}
1125
Andre Guedesf9b49302011-06-30 19:20:53 -03001126static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1127 struct sk_buff *skb)
1128{
1129 struct hci_cp_read_local_ext_features cp;
1130 __u8 status = *((__u8 *) skb->data);
1131
1132 BT_DBG("%s status 0x%x", hdev->name, status);
1133
1134 if (status)
1135 return;
1136
1137 cp.page = 0x01;
1138 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1139}
1140
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001141static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1142{
1143 BT_DBG("%s status 0x%x", hdev->name, status);
1144
1145 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001146 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001147 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001148 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001149 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001150 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001151 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001152 return;
1153 }
1154
Andre Guedes89352e72011-11-04 14:16:53 -03001155 set_bit(HCI_INQUIRY, &hdev->flags);
1156
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001157 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001158 hci_discovery_set_state(hdev, DISCOVERY_INQUIRY);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001159 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001160}
1161
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1163{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001164 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001167 BT_DBG("%s status 0x%x", hdev->name, status);
1168
1169 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170 if (!cp)
1171 return;
1172
1173 hci_dev_lock(hdev);
1174
1175 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1176
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001177 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178
1179 if (status) {
1180 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001181 if (status != 0x0c || conn->attempt > 2) {
1182 conn->state = BT_CLOSED;
1183 hci_proto_connect_cfm(conn, status);
1184 hci_conn_del(conn);
1185 } else
1186 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187 }
1188 } else {
1189 if (!conn) {
1190 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1191 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001192 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 conn->link_mode |= HCI_LM_MASTER;
1194 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001195 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196 }
1197 }
1198
1199 hci_dev_unlock(hdev);
1200}
1201
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001202static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001204 struct hci_cp_add_sco *cp;
1205 struct hci_conn *acl, *sco;
1206 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001208 BT_DBG("%s status 0x%x", hdev->name, status);
1209
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001210 if (!status)
1211 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001213 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1214 if (!cp)
1215 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001217 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001219 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001220
1221 hci_dev_lock(hdev);
1222
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001223 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001224 if (acl) {
1225 sco = acl->link;
1226 if (sco) {
1227 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001228
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001229 hci_proto_connect_cfm(sco, status);
1230 hci_conn_del(sco);
1231 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001232 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001233
1234 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235}
1236
Marcel Holtmannf8558552008-07-14 20:13:49 +02001237static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1238{
1239 struct hci_cp_auth_requested *cp;
1240 struct hci_conn *conn;
1241
1242 BT_DBG("%s status 0x%x", hdev->name, status);
1243
1244 if (!status)
1245 return;
1246
1247 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1248 if (!cp)
1249 return;
1250
1251 hci_dev_lock(hdev);
1252
1253 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1254 if (conn) {
1255 if (conn->state == BT_CONFIG) {
1256 hci_proto_connect_cfm(conn, status);
1257 hci_conn_put(conn);
1258 }
1259 }
1260
1261 hci_dev_unlock(hdev);
1262}
1263
1264static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1265{
1266 struct hci_cp_set_conn_encrypt *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_SET_CONN_ENCRYPT);
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
Johan Hedberg127178d2010-11-18 22:22:29 +02001291static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001292 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001293{
Johan Hedberg392599b2010-11-18 22:22:28 +02001294 if (conn->state != BT_CONFIG || !conn->out)
1295 return 0;
1296
Johan Hedberg765c2a92011-01-19 12:06:52 +05301297 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001298 return 0;
1299
1300 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001301 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001302 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001303 conn->pending_sec_level != BT_SECURITY_HIGH &&
1304 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001305 return 0;
1306
Johan Hedberg392599b2010-11-18 22:22:28 +02001307 return 1;
1308}
1309
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001310static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1311{
1312 struct hci_cp_remote_name_req cp;
1313
1314 memset(&cp, 0, sizeof(cp));
1315
1316 bacpy(&cp.bdaddr, &e->data.bdaddr);
1317 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1318 cp.pscan_mode = e->data.pscan_mode;
1319 cp.clock_offset = e->data.clock_offset;
1320
1321 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1322}
1323
Johan Hedbergb644ba32012-01-17 21:48:47 +02001324static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001325{
1326 struct discovery_state *discov = &hdev->discovery;
1327 struct inquiry_entry *e;
1328
Johan Hedbergb644ba32012-01-17 21:48:47 +02001329 if (list_empty(&discov->resolve))
1330 return false;
1331
1332 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1333 if (hci_resolve_name(hdev, e) == 0) {
1334 e->name_state = NAME_PENDING;
1335 return true;
1336 }
1337
1338 return false;
1339}
1340
1341static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1342 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1343{
1344 struct discovery_state *discov = &hdev->discovery;
1345 struct inquiry_entry *e;
1346
1347 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1348 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
1349 name, name_len, conn->dev_class);
1350
1351 if (discov->state == DISCOVERY_STOPPED)
1352 return;
1353
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001354 if (discov->state == DISCOVERY_STOPPING)
1355 goto discov_complete;
1356
1357 if (discov->state != DISCOVERY_RESOLVING)
1358 return;
1359
1360 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1361 if (e) {
1362 e->name_state = NAME_KNOWN;
1363 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001364 if (name)
1365 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1366 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001367 }
1368
Johan Hedbergb644ba32012-01-17 21:48:47 +02001369 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001370 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001371
1372discov_complete:
1373 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1374}
1375
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001376static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1377{
Johan Hedberg127178d2010-11-18 22:22:29 +02001378 struct hci_cp_remote_name_req *cp;
1379 struct hci_conn *conn;
1380
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001381 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001382
1383 /* If successful wait for the name req complete event before
1384 * checking for the need to do authentication */
1385 if (!status)
1386 return;
1387
1388 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1389 if (!cp)
1390 return;
1391
1392 hci_dev_lock(hdev);
1393
1394 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001395
1396 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1397 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1398
Johan Hedberg79c6c702011-04-28 11:28:55 -07001399 if (!conn)
1400 goto unlock;
1401
1402 if (!hci_outgoing_auth_needed(hdev, conn))
1403 goto unlock;
1404
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001405 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001406 struct hci_cp_auth_requested cp;
1407 cp.handle = __cpu_to_le16(conn->handle);
1408 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1409 }
1410
Johan Hedberg79c6c702011-04-28 11:28:55 -07001411unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001412 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001413}
1414
Marcel Holtmann769be972008-07-14 20:13:49 +02001415static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1416{
1417 struct hci_cp_read_remote_features *cp;
1418 struct hci_conn *conn;
1419
1420 BT_DBG("%s status 0x%x", hdev->name, status);
1421
1422 if (!status)
1423 return;
1424
1425 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1426 if (!cp)
1427 return;
1428
1429 hci_dev_lock(hdev);
1430
1431 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1432 if (conn) {
1433 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001434 hci_proto_connect_cfm(conn, status);
1435 hci_conn_put(conn);
1436 }
1437 }
1438
1439 hci_dev_unlock(hdev);
1440}
1441
1442static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1443{
1444 struct hci_cp_read_remote_ext_features *cp;
1445 struct hci_conn *conn;
1446
1447 BT_DBG("%s status 0x%x", hdev->name, status);
1448
1449 if (!status)
1450 return;
1451
1452 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1453 if (!cp)
1454 return;
1455
1456 hci_dev_lock(hdev);
1457
1458 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1459 if (conn) {
1460 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001461 hci_proto_connect_cfm(conn, status);
1462 hci_conn_put(conn);
1463 }
1464 }
1465
1466 hci_dev_unlock(hdev);
1467}
1468
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001469static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1470{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001471 struct hci_cp_setup_sync_conn *cp;
1472 struct hci_conn *acl, *sco;
1473 __u16 handle;
1474
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001475 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001476
1477 if (!status)
1478 return;
1479
1480 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1481 if (!cp)
1482 return;
1483
1484 handle = __le16_to_cpu(cp->handle);
1485
1486 BT_DBG("%s handle %d", hdev->name, handle);
1487
1488 hci_dev_lock(hdev);
1489
1490 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001491 if (acl) {
1492 sco = acl->link;
1493 if (sco) {
1494 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001495
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001496 hci_proto_connect_cfm(sco, status);
1497 hci_conn_del(sco);
1498 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001499 }
1500
1501 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001502}
1503
1504static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1505{
1506 struct hci_cp_sniff_mode *cp;
1507 struct hci_conn *conn;
1508
1509 BT_DBG("%s status 0x%x", hdev->name, status);
1510
1511 if (!status)
1512 return;
1513
1514 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1515 if (!cp)
1516 return;
1517
1518 hci_dev_lock(hdev);
1519
1520 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001521 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001522 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001523
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001524 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001525 hci_sco_setup(conn, status);
1526 }
1527
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001528 hci_dev_unlock(hdev);
1529}
1530
1531static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1532{
1533 struct hci_cp_exit_sniff_mode *cp;
1534 struct hci_conn *conn;
1535
1536 BT_DBG("%s status 0x%x", hdev->name, status);
1537
1538 if (!status)
1539 return;
1540
1541 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1542 if (!cp)
1543 return;
1544
1545 hci_dev_lock(hdev);
1546
1547 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001548 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001549 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001550
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001551 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001552 hci_sco_setup(conn, status);
1553 }
1554
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001555 hci_dev_unlock(hdev);
1556}
1557
Johan Hedberg88c3df12012-02-09 14:27:38 +02001558static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1559{
1560 struct hci_cp_disconnect *cp;
1561 struct hci_conn *conn;
1562
1563 if (!status)
1564 return;
1565
1566 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1567 if (!cp)
1568 return;
1569
1570 hci_dev_lock(hdev);
1571
1572 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1573 if (conn)
1574 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1575 conn->dst_type, status);
1576
1577 hci_dev_unlock(hdev);
1578}
1579
Ville Tervofcd89c02011-02-10 22:38:47 -03001580static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1581{
1582 struct hci_cp_le_create_conn *cp;
1583 struct hci_conn *conn;
1584
1585 BT_DBG("%s status 0x%x", hdev->name, status);
1586
1587 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1588 if (!cp)
1589 return;
1590
1591 hci_dev_lock(hdev);
1592
1593 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1594
1595 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1596 conn);
1597
1598 if (status) {
1599 if (conn && conn->state == BT_CONNECT) {
1600 conn->state = BT_CLOSED;
1601 hci_proto_connect_cfm(conn, status);
1602 hci_conn_del(conn);
1603 }
1604 } else {
1605 if (!conn) {
1606 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001607 if (conn) {
1608 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001609 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001610 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001611 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001612 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001613 }
1614 }
1615
1616 hci_dev_unlock(hdev);
1617}
1618
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001619static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1620{
1621 BT_DBG("%s status 0x%x", hdev->name, status);
1622}
1623
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001624static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1625{
1626 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001627 struct discovery_state *discov = &hdev->discovery;
1628 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001629
1630 BT_DBG("%s status %d", hdev->name, status);
1631
Johan Hedberg23bb5762010-12-21 23:01:27 +02001632 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001633
1634 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001635
1636 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1637 return;
1638
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001639 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001640 return;
1641
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001642 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001643
1644 if (discov->state != DISCOVERY_INQUIRY)
1645 goto unlock;
1646
1647 if (list_empty(&discov->resolve)) {
1648 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1649 goto unlock;
1650 }
1651
1652 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1653 if (e && hci_resolve_name(hdev, e) == 0) {
1654 e->name_state = NAME_PENDING;
1655 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1656 } else {
1657 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1658 }
1659
1660unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001661 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001662}
1663
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1665{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001666 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001667 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668 int num_rsp = *((__u8 *) skb->data);
1669
1670 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1671
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001672 if (!num_rsp)
1673 return;
1674
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001676
Johan Hedberge17acd42011-03-30 23:57:16 +03001677 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg31754052012-01-04 13:39:52 +02001678 bool name_known;
1679
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 bacpy(&data.bdaddr, &info->bdaddr);
1681 data.pscan_rep_mode = info->pscan_rep_mode;
1682 data.pscan_period_mode = info->pscan_period_mode;
1683 data.pscan_mode = info->pscan_mode;
1684 memcpy(data.dev_class, info->dev_class, 3);
1685 data.clock_offset = info->clock_offset;
1686 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001687 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001688
1689 name_known = hci_inquiry_cache_update(hdev, &data, false);
Johan Hedberg48264f02011-11-09 13:58:58 +02001690 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Andre Guedes7d262f82012-01-10 18:20:49 -03001691 info->dev_class, 0, !name_known,
1692 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001694
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695 hci_dev_unlock(hdev);
1696}
1697
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001698static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001700 struct hci_ev_conn_complete *ev = (void *) skb->data;
1701 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001703 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001704
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001706
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001707 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001708 if (!conn) {
1709 if (ev->link_type != SCO_LINK)
1710 goto unlock;
1711
1712 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1713 if (!conn)
1714 goto unlock;
1715
1716 conn->type = SCO_LINK;
1717 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001718
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001719 if (!ev->status) {
1720 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001721
1722 if (conn->type == ACL_LINK) {
1723 conn->state = BT_CONFIG;
1724 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001725 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001726 } else
1727 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001728
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001729 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001730 hci_conn_add_sysfs(conn);
1731
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001732 if (test_bit(HCI_AUTH, &hdev->flags))
1733 conn->link_mode |= HCI_LM_AUTH;
1734
1735 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1736 conn->link_mode |= HCI_LM_ENCRYPT;
1737
1738 /* Get remote features */
1739 if (conn->type == ACL_LINK) {
1740 struct hci_cp_read_remote_features cp;
1741 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001742 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1743 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001744 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001745
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001746 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001747 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001748 struct hci_cp_change_conn_ptype cp;
1749 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001750 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1751 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1752 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001753 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001754 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001755 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001756 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001757 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001758 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001759 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001760
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001761 if (conn->type == ACL_LINK)
1762 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001763
Marcel Holtmann769be972008-07-14 20:13:49 +02001764 if (ev->status) {
1765 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001766 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001767 } else if (ev->link_type != ACL_LINK)
1768 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001769
1770unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001772
1773 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774}
1775
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1777{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001778 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 int mask = hdev->link_mode;
1780
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001781 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1782 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783
1784 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1785
Szymon Janc138d22e2011-02-17 16:44:23 +01001786 if ((mask & HCI_LM_ACCEPT) &&
1787 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001789 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791
1792 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001793
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001794 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1795 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001796 memcpy(ie->data.dev_class, ev->dev_class, 3);
1797
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1799 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001800 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1801 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001802 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 hci_dev_unlock(hdev);
1804 return;
1805 }
1806 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001807
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 memcpy(conn->dev_class, ev->dev_class, 3);
1809 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001810
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 hci_dev_unlock(hdev);
1812
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001813 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1814 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001816 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001818 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1819 cp.role = 0x00; /* Become master */
1820 else
1821 cp.role = 0x01; /* Remain slave */
1822
1823 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1824 sizeof(cp), &cp);
1825 } else {
1826 struct hci_cp_accept_sync_conn_req cp;
1827
1828 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001829 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001830
1831 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1832 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1833 cp.max_latency = cpu_to_le16(0xffff);
1834 cp.content_format = cpu_to_le16(hdev->voice_setting);
1835 cp.retrans_effort = 0xff;
1836
1837 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1838 sizeof(cp), &cp);
1839 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 } else {
1841 /* Connection rejected */
1842 struct hci_cp_reject_conn_req cp;
1843
1844 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001845 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001846 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847 }
1848}
1849
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1851{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001852 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001853 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854
1855 BT_DBG("%s status %d", hdev->name, ev->status);
1856
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 hci_dev_lock(hdev);
1858
Marcel Holtmann04837f62006-07-03 10:02:33 +02001859 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001860 if (!conn)
1861 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001862
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001863 if (ev->status == 0)
1864 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865
Johan Hedbergb644ba32012-01-17 21:48:47 +02001866 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1867 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001868 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001869 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1870 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001871 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001872 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001873 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001874 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001875
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001876 if (ev->status == 0) {
1877 hci_proto_disconn_cfm(conn, ev->reason);
1878 hci_conn_del(conn);
1879 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001880
1881unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 hci_dev_unlock(hdev);
1883}
1884
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001885static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1886{
1887 struct hci_ev_auth_complete *ev = (void *) skb->data;
1888 struct hci_conn *conn;
1889
1890 BT_DBG("%s status %d", hdev->name, ev->status);
1891
1892 hci_dev_lock(hdev);
1893
1894 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001895 if (!conn)
1896 goto unlock;
1897
1898 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001899 if (!hci_conn_ssp_enabled(conn) &&
1900 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001901 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001902 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001903 conn->link_mode |= HCI_LM_AUTH;
1904 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001905 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001906 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001907 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
1908 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001909 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001910
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001911 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1912 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001913
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001914 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001915 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001916 struct hci_cp_set_conn_encrypt cp;
1917 cp.handle = ev->handle;
1918 cp.encrypt = 0x01;
1919 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1920 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001921 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001922 conn->state = BT_CONNECTED;
1923 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001924 hci_conn_put(conn);
1925 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001926 } else {
1927 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001928
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001929 hci_conn_hold(conn);
1930 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1931 hci_conn_put(conn);
1932 }
1933
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001934 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001935 if (!ev->status) {
1936 struct hci_cp_set_conn_encrypt cp;
1937 cp.handle = ev->handle;
1938 cp.encrypt = 0x01;
1939 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1940 &cp);
1941 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001942 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001943 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001944 }
1945 }
1946
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001947unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001948 hci_dev_unlock(hdev);
1949}
1950
1951static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1952{
Johan Hedberg127178d2010-11-18 22:22:29 +02001953 struct hci_ev_remote_name *ev = (void *) skb->data;
1954 struct hci_conn *conn;
1955
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001956 BT_DBG("%s", hdev->name);
1957
1958 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001959
1960 hci_dev_lock(hdev);
1961
1962 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001963
1964 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1965 goto check_auth;
1966
1967 if (ev->status == 0)
1968 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1969 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1970 else
1971 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1972
1973check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001974 if (!conn)
1975 goto unlock;
1976
1977 if (!hci_outgoing_auth_needed(hdev, conn))
1978 goto unlock;
1979
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001980 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001981 struct hci_cp_auth_requested cp;
1982 cp.handle = __cpu_to_le16(conn->handle);
1983 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1984 }
1985
Johan Hedberg79c6c702011-04-28 11:28:55 -07001986unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001987 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001988}
1989
1990static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1991{
1992 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1993 struct hci_conn *conn;
1994
1995 BT_DBG("%s status %d", hdev->name, ev->status);
1996
1997 hci_dev_lock(hdev);
1998
1999 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2000 if (conn) {
2001 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002002 if (ev->encrypt) {
2003 /* Encryption implies authentication */
2004 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002005 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002006 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002007 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002008 conn->link_mode &= ~HCI_LM_ENCRYPT;
2009 }
2010
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002011 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002012
Marcel Holtmannf8558552008-07-14 20:13:49 +02002013 if (conn->state == BT_CONFIG) {
2014 if (!ev->status)
2015 conn->state = BT_CONNECTED;
2016
2017 hci_proto_connect_cfm(conn, ev->status);
2018 hci_conn_put(conn);
2019 } else
2020 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002021 }
2022
2023 hci_dev_unlock(hdev);
2024}
2025
2026static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2027{
2028 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2029 struct hci_conn *conn;
2030
2031 BT_DBG("%s status %d", hdev->name, ev->status);
2032
2033 hci_dev_lock(hdev);
2034
2035 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2036 if (conn) {
2037 if (!ev->status)
2038 conn->link_mode |= HCI_LM_SECURE;
2039
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002040 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002041
2042 hci_key_change_cfm(conn, ev->status);
2043 }
2044
2045 hci_dev_unlock(hdev);
2046}
2047
2048static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2049{
2050 struct hci_ev_remote_features *ev = (void *) skb->data;
2051 struct hci_conn *conn;
2052
2053 BT_DBG("%s status %d", hdev->name, ev->status);
2054
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002055 hci_dev_lock(hdev);
2056
2057 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002058 if (!conn)
2059 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002060
Johan Hedbergccd556f2010-11-10 17:11:51 +02002061 if (!ev->status)
2062 memcpy(conn->features, ev->features, 8);
2063
2064 if (conn->state != BT_CONFIG)
2065 goto unlock;
2066
2067 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2068 struct hci_cp_read_remote_ext_features cp;
2069 cp.handle = ev->handle;
2070 cp.page = 0x01;
2071 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002072 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002073 goto unlock;
2074 }
2075
Johan Hedberg127178d2010-11-18 22:22:29 +02002076 if (!ev->status) {
2077 struct hci_cp_remote_name_req cp;
2078 memset(&cp, 0, sizeof(cp));
2079 bacpy(&cp.bdaddr, &conn->dst);
2080 cp.pscan_rep_mode = 0x02;
2081 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002082 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2083 mgmt_device_connected(hdev, &conn->dst, conn->type,
2084 conn->dst_type, NULL, 0,
2085 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002086
Johan Hedberg127178d2010-11-18 22:22:29 +02002087 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002088 conn->state = BT_CONNECTED;
2089 hci_proto_connect_cfm(conn, ev->status);
2090 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002091 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002092
Johan Hedbergccd556f2010-11-10 17:11:51 +02002093unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002094 hci_dev_unlock(hdev);
2095}
2096
2097static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2098{
2099 BT_DBG("%s", hdev->name);
2100}
2101
2102static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2103{
2104 BT_DBG("%s", hdev->name);
2105}
2106
2107static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2108{
2109 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2110 __u16 opcode;
2111
2112 skb_pull(skb, sizeof(*ev));
2113
2114 opcode = __le16_to_cpu(ev->opcode);
2115
2116 switch (opcode) {
2117 case HCI_OP_INQUIRY_CANCEL:
2118 hci_cc_inquiry_cancel(hdev, skb);
2119 break;
2120
2121 case HCI_OP_EXIT_PERIODIC_INQ:
2122 hci_cc_exit_periodic_inq(hdev, skb);
2123 break;
2124
2125 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2126 hci_cc_remote_name_req_cancel(hdev, skb);
2127 break;
2128
2129 case HCI_OP_ROLE_DISCOVERY:
2130 hci_cc_role_discovery(hdev, skb);
2131 break;
2132
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002133 case HCI_OP_READ_LINK_POLICY:
2134 hci_cc_read_link_policy(hdev, skb);
2135 break;
2136
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002137 case HCI_OP_WRITE_LINK_POLICY:
2138 hci_cc_write_link_policy(hdev, skb);
2139 break;
2140
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002141 case HCI_OP_READ_DEF_LINK_POLICY:
2142 hci_cc_read_def_link_policy(hdev, skb);
2143 break;
2144
2145 case HCI_OP_WRITE_DEF_LINK_POLICY:
2146 hci_cc_write_def_link_policy(hdev, skb);
2147 break;
2148
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002149 case HCI_OP_RESET:
2150 hci_cc_reset(hdev, skb);
2151 break;
2152
2153 case HCI_OP_WRITE_LOCAL_NAME:
2154 hci_cc_write_local_name(hdev, skb);
2155 break;
2156
2157 case HCI_OP_READ_LOCAL_NAME:
2158 hci_cc_read_local_name(hdev, skb);
2159 break;
2160
2161 case HCI_OP_WRITE_AUTH_ENABLE:
2162 hci_cc_write_auth_enable(hdev, skb);
2163 break;
2164
2165 case HCI_OP_WRITE_ENCRYPT_MODE:
2166 hci_cc_write_encrypt_mode(hdev, skb);
2167 break;
2168
2169 case HCI_OP_WRITE_SCAN_ENABLE:
2170 hci_cc_write_scan_enable(hdev, skb);
2171 break;
2172
2173 case HCI_OP_READ_CLASS_OF_DEV:
2174 hci_cc_read_class_of_dev(hdev, skb);
2175 break;
2176
2177 case HCI_OP_WRITE_CLASS_OF_DEV:
2178 hci_cc_write_class_of_dev(hdev, skb);
2179 break;
2180
2181 case HCI_OP_READ_VOICE_SETTING:
2182 hci_cc_read_voice_setting(hdev, skb);
2183 break;
2184
2185 case HCI_OP_WRITE_VOICE_SETTING:
2186 hci_cc_write_voice_setting(hdev, skb);
2187 break;
2188
2189 case HCI_OP_HOST_BUFFER_SIZE:
2190 hci_cc_host_buffer_size(hdev, skb);
2191 break;
2192
Marcel Holtmann333140b2008-07-14 20:13:48 +02002193 case HCI_OP_READ_SSP_MODE:
2194 hci_cc_read_ssp_mode(hdev, skb);
2195 break;
2196
2197 case HCI_OP_WRITE_SSP_MODE:
2198 hci_cc_write_ssp_mode(hdev, skb);
2199 break;
2200
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002201 case HCI_OP_READ_LOCAL_VERSION:
2202 hci_cc_read_local_version(hdev, skb);
2203 break;
2204
2205 case HCI_OP_READ_LOCAL_COMMANDS:
2206 hci_cc_read_local_commands(hdev, skb);
2207 break;
2208
2209 case HCI_OP_READ_LOCAL_FEATURES:
2210 hci_cc_read_local_features(hdev, skb);
2211 break;
2212
Andre Guedes971e3a42011-06-30 19:20:52 -03002213 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2214 hci_cc_read_local_ext_features(hdev, skb);
2215 break;
2216
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002217 case HCI_OP_READ_BUFFER_SIZE:
2218 hci_cc_read_buffer_size(hdev, skb);
2219 break;
2220
2221 case HCI_OP_READ_BD_ADDR:
2222 hci_cc_read_bd_addr(hdev, skb);
2223 break;
2224
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002225 case HCI_OP_READ_DATA_BLOCK_SIZE:
2226 hci_cc_read_data_block_size(hdev, skb);
2227 break;
2228
Johan Hedberg23bb5762010-12-21 23:01:27 +02002229 case HCI_OP_WRITE_CA_TIMEOUT:
2230 hci_cc_write_ca_timeout(hdev, skb);
2231 break;
2232
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002233 case HCI_OP_READ_FLOW_CONTROL_MODE:
2234 hci_cc_read_flow_control_mode(hdev, skb);
2235 break;
2236
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002237 case HCI_OP_READ_LOCAL_AMP_INFO:
2238 hci_cc_read_local_amp_info(hdev, skb);
2239 break;
2240
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002241 case HCI_OP_DELETE_STORED_LINK_KEY:
2242 hci_cc_delete_stored_link_key(hdev, skb);
2243 break;
2244
Johan Hedbergd5859e22011-01-25 01:19:58 +02002245 case HCI_OP_SET_EVENT_MASK:
2246 hci_cc_set_event_mask(hdev, skb);
2247 break;
2248
2249 case HCI_OP_WRITE_INQUIRY_MODE:
2250 hci_cc_write_inquiry_mode(hdev, skb);
2251 break;
2252
2253 case HCI_OP_READ_INQ_RSP_TX_POWER:
2254 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2255 break;
2256
2257 case HCI_OP_SET_EVENT_FLT:
2258 hci_cc_set_event_flt(hdev, skb);
2259 break;
2260
Johan Hedberg980e1a52011-01-22 06:10:07 +02002261 case HCI_OP_PIN_CODE_REPLY:
2262 hci_cc_pin_code_reply(hdev, skb);
2263 break;
2264
2265 case HCI_OP_PIN_CODE_NEG_REPLY:
2266 hci_cc_pin_code_neg_reply(hdev, skb);
2267 break;
2268
Szymon Jancc35938b2011-03-22 13:12:21 +01002269 case HCI_OP_READ_LOCAL_OOB_DATA:
2270 hci_cc_read_local_oob_data_reply(hdev, skb);
2271 break;
2272
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002273 case HCI_OP_LE_READ_BUFFER_SIZE:
2274 hci_cc_le_read_buffer_size(hdev, skb);
2275 break;
2276
Johan Hedberga5c29682011-02-19 12:05:57 -03002277 case HCI_OP_USER_CONFIRM_REPLY:
2278 hci_cc_user_confirm_reply(hdev, skb);
2279 break;
2280
2281 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2282 hci_cc_user_confirm_neg_reply(hdev, skb);
2283 break;
2284
Brian Gix1143d452011-11-23 08:28:34 -08002285 case HCI_OP_USER_PASSKEY_REPLY:
2286 hci_cc_user_passkey_reply(hdev, skb);
2287 break;
2288
2289 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2290 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002291
2292 case HCI_OP_LE_SET_SCAN_PARAM:
2293 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002294 break;
2295
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002296 case HCI_OP_LE_SET_SCAN_ENABLE:
2297 hci_cc_le_set_scan_enable(hdev, skb);
2298 break;
2299
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002300 case HCI_OP_LE_LTK_REPLY:
2301 hci_cc_le_ltk_reply(hdev, skb);
2302 break;
2303
2304 case HCI_OP_LE_LTK_NEG_REPLY:
2305 hci_cc_le_ltk_neg_reply(hdev, skb);
2306 break;
2307
Andre Guedesf9b49302011-06-30 19:20:53 -03002308 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2309 hci_cc_write_le_host_supported(hdev, skb);
2310 break;
2311
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002312 default:
2313 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2314 break;
2315 }
2316
Ville Tervo6bd32322011-02-16 16:32:41 +02002317 if (ev->opcode != HCI_OP_NOP)
2318 del_timer(&hdev->cmd_timer);
2319
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002320 if (ev->ncmd) {
2321 atomic_set(&hdev->cmd_cnt, 1);
2322 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002323 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002324 }
2325}
2326
2327static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2328{
2329 struct hci_ev_cmd_status *ev = (void *) skb->data;
2330 __u16 opcode;
2331
2332 skb_pull(skb, sizeof(*ev));
2333
2334 opcode = __le16_to_cpu(ev->opcode);
2335
2336 switch (opcode) {
2337 case HCI_OP_INQUIRY:
2338 hci_cs_inquiry(hdev, ev->status);
2339 break;
2340
2341 case HCI_OP_CREATE_CONN:
2342 hci_cs_create_conn(hdev, ev->status);
2343 break;
2344
2345 case HCI_OP_ADD_SCO:
2346 hci_cs_add_sco(hdev, ev->status);
2347 break;
2348
Marcel Holtmannf8558552008-07-14 20:13:49 +02002349 case HCI_OP_AUTH_REQUESTED:
2350 hci_cs_auth_requested(hdev, ev->status);
2351 break;
2352
2353 case HCI_OP_SET_CONN_ENCRYPT:
2354 hci_cs_set_conn_encrypt(hdev, ev->status);
2355 break;
2356
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002357 case HCI_OP_REMOTE_NAME_REQ:
2358 hci_cs_remote_name_req(hdev, ev->status);
2359 break;
2360
Marcel Holtmann769be972008-07-14 20:13:49 +02002361 case HCI_OP_READ_REMOTE_FEATURES:
2362 hci_cs_read_remote_features(hdev, ev->status);
2363 break;
2364
2365 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2366 hci_cs_read_remote_ext_features(hdev, ev->status);
2367 break;
2368
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002369 case HCI_OP_SETUP_SYNC_CONN:
2370 hci_cs_setup_sync_conn(hdev, ev->status);
2371 break;
2372
2373 case HCI_OP_SNIFF_MODE:
2374 hci_cs_sniff_mode(hdev, ev->status);
2375 break;
2376
2377 case HCI_OP_EXIT_SNIFF_MODE:
2378 hci_cs_exit_sniff_mode(hdev, ev->status);
2379 break;
2380
Johan Hedberg8962ee72011-01-20 12:40:27 +02002381 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002382 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002383 break;
2384
Ville Tervofcd89c02011-02-10 22:38:47 -03002385 case HCI_OP_LE_CREATE_CONN:
2386 hci_cs_le_create_conn(hdev, ev->status);
2387 break;
2388
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002389 case HCI_OP_LE_START_ENC:
2390 hci_cs_le_start_enc(hdev, ev->status);
2391 break;
2392
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002393 default:
2394 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2395 break;
2396 }
2397
Ville Tervo6bd32322011-02-16 16:32:41 +02002398 if (ev->opcode != HCI_OP_NOP)
2399 del_timer(&hdev->cmd_timer);
2400
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002401 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002402 atomic_set(&hdev->cmd_cnt, 1);
2403 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002404 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002405 }
2406}
2407
2408static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2409{
2410 struct hci_ev_role_change *ev = (void *) skb->data;
2411 struct hci_conn *conn;
2412
2413 BT_DBG("%s status %d", hdev->name, ev->status);
2414
2415 hci_dev_lock(hdev);
2416
2417 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2418 if (conn) {
2419 if (!ev->status) {
2420 if (ev->role)
2421 conn->link_mode &= ~HCI_LM_MASTER;
2422 else
2423 conn->link_mode |= HCI_LM_MASTER;
2424 }
2425
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002426 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002427
2428 hci_role_switch_cfm(conn, ev->status, ev->role);
2429 }
2430
2431 hci_dev_unlock(hdev);
2432}
2433
Linus Torvalds1da177e2005-04-16 15:20:36 -07002434static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2435{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002436 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437 int i;
2438
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002439 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2440 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2441 return;
2442 }
2443
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002444 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2445 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446 BT_DBG("%s bad parameters", hdev->name);
2447 return;
2448 }
2449
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002450 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2451
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002452 for (i = 0; i < ev->num_hndl; i++) {
2453 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002454 struct hci_conn *conn;
2455 __u16 handle, count;
2456
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002457 handle = __le16_to_cpu(info->handle);
2458 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002459
2460 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002461 if (!conn)
2462 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002463
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002464 conn->sent -= count;
2465
2466 switch (conn->type) {
2467 case ACL_LINK:
2468 hdev->acl_cnt += count;
2469 if (hdev->acl_cnt > hdev->acl_pkts)
2470 hdev->acl_cnt = hdev->acl_pkts;
2471 break;
2472
2473 case LE_LINK:
2474 if (hdev->le_pkts) {
2475 hdev->le_cnt += count;
2476 if (hdev->le_cnt > hdev->le_pkts)
2477 hdev->le_cnt = hdev->le_pkts;
2478 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002479 hdev->acl_cnt += count;
2480 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002481 hdev->acl_cnt = hdev->acl_pkts;
2482 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002483 break;
2484
2485 case SCO_LINK:
2486 hdev->sco_cnt += count;
2487 if (hdev->sco_cnt > hdev->sco_pkts)
2488 hdev->sco_cnt = hdev->sco_pkts;
2489 break;
2490
2491 default:
2492 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2493 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494 }
2495 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002496
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002497 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498}
2499
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002500static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2501 struct sk_buff *skb)
2502{
2503 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2504 int i;
2505
2506 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2507 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2508 return;
2509 }
2510
2511 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2512 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2513 BT_DBG("%s bad parameters", hdev->name);
2514 return;
2515 }
2516
2517 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2518 ev->num_hndl);
2519
2520 for (i = 0; i < ev->num_hndl; i++) {
2521 struct hci_comp_blocks_info *info = &ev->handles[i];
2522 struct hci_conn *conn;
2523 __u16 handle, block_count;
2524
2525 handle = __le16_to_cpu(info->handle);
2526 block_count = __le16_to_cpu(info->blocks);
2527
2528 conn = hci_conn_hash_lookup_handle(hdev, handle);
2529 if (!conn)
2530 continue;
2531
2532 conn->sent -= block_count;
2533
2534 switch (conn->type) {
2535 case ACL_LINK:
2536 hdev->block_cnt += block_count;
2537 if (hdev->block_cnt > hdev->num_blocks)
2538 hdev->block_cnt = hdev->num_blocks;
2539 break;
2540
2541 default:
2542 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2543 break;
2544 }
2545 }
2546
2547 queue_work(hdev->workqueue, &hdev->tx_work);
2548}
2549
Marcel Holtmann04837f62006-07-03 10:02:33 +02002550static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002552 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002553 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554
2555 BT_DBG("%s status %d", hdev->name, ev->status);
2556
2557 hci_dev_lock(hdev);
2558
Marcel Holtmann04837f62006-07-03 10:02:33 +02002559 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2560 if (conn) {
2561 conn->mode = ev->mode;
2562 conn->interval = __le16_to_cpu(ev->interval);
2563
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002564 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002565 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002566 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002567 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002568 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002569 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002570
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002571 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002572 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002573 }
2574
2575 hci_dev_unlock(hdev);
2576}
2577
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2579{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002580 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2581 struct hci_conn *conn;
2582
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002583 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002584
2585 hci_dev_lock(hdev);
2586
2587 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002588 if (!conn)
2589 goto unlock;
2590
2591 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002592 hci_conn_hold(conn);
2593 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2594 hci_conn_put(conn);
2595 }
2596
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002597 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002598 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2599 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002600 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002601 u8 secure;
2602
2603 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2604 secure = 1;
2605 else
2606 secure = 0;
2607
Johan Hedberg744cf192011-11-08 20:40:14 +02002608 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002609 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002610
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002611unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002612 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002613}
2614
Linus Torvalds1da177e2005-04-16 15:20:36 -07002615static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2616{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002617 struct hci_ev_link_key_req *ev = (void *) skb->data;
2618 struct hci_cp_link_key_reply cp;
2619 struct hci_conn *conn;
2620 struct link_key *key;
2621
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002622 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002623
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002624 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002625 return;
2626
2627 hci_dev_lock(hdev);
2628
2629 key = hci_find_link_key(hdev, &ev->bdaddr);
2630 if (!key) {
2631 BT_DBG("%s link key not found for %s", hdev->name,
2632 batostr(&ev->bdaddr));
2633 goto not_found;
2634 }
2635
2636 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2637 batostr(&ev->bdaddr));
2638
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002639 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002640 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002641 BT_DBG("%s ignoring debug key", hdev->name);
2642 goto not_found;
2643 }
2644
2645 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002646 if (conn) {
2647 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2648 conn->auth_type != 0xff &&
2649 (conn->auth_type & 0x01)) {
2650 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2651 goto not_found;
2652 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002653
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002654 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2655 conn->pending_sec_level == BT_SECURITY_HIGH) {
2656 BT_DBG("%s ignoring key unauthenticated for high \
2657 security", hdev->name);
2658 goto not_found;
2659 }
2660
2661 conn->key_type = key->type;
2662 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002663 }
2664
2665 bacpy(&cp.bdaddr, &ev->bdaddr);
2666 memcpy(cp.link_key, key->val, 16);
2667
2668 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2669
2670 hci_dev_unlock(hdev);
2671
2672 return;
2673
2674not_found:
2675 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2676 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002677}
2678
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2680{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002681 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2682 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002683 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002684
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002685 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002686
2687 hci_dev_lock(hdev);
2688
2689 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2690 if (conn) {
2691 hci_conn_hold(conn);
2692 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002693 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002694
2695 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2696 conn->key_type = ev->key_type;
2697
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002698 hci_conn_put(conn);
2699 }
2700
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002701 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002702 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002703 ev->key_type, pin_len);
2704
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002705 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706}
2707
Marcel Holtmann04837f62006-07-03 10:02:33 +02002708static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2709{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002710 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002711 struct hci_conn *conn;
2712
2713 BT_DBG("%s status %d", hdev->name, ev->status);
2714
2715 hci_dev_lock(hdev);
2716
2717 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002718 if (conn && !ev->status) {
2719 struct inquiry_entry *ie;
2720
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002721 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2722 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723 ie->data.clock_offset = ev->clock_offset;
2724 ie->timestamp = jiffies;
2725 }
2726 }
2727
2728 hci_dev_unlock(hdev);
2729}
2730
Marcel Holtmanna8746412008-07-14 20:13:46 +02002731static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2732{
2733 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2734 struct hci_conn *conn;
2735
2736 BT_DBG("%s status %d", hdev->name, ev->status);
2737
2738 hci_dev_lock(hdev);
2739
2740 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2741 if (conn && !ev->status)
2742 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2743
2744 hci_dev_unlock(hdev);
2745}
2746
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002747static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2748{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002749 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002750 struct inquiry_entry *ie;
2751
2752 BT_DBG("%s", hdev->name);
2753
2754 hci_dev_lock(hdev);
2755
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002756 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2757 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002758 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2759 ie->timestamp = jiffies;
2760 }
2761
2762 hci_dev_unlock(hdev);
2763}
2764
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002765static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2766{
2767 struct inquiry_data data;
2768 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg31754052012-01-04 13:39:52 +02002769 bool name_known;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002770
2771 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2772
2773 if (!num_rsp)
2774 return;
2775
2776 hci_dev_lock(hdev);
2777
2778 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002779 struct inquiry_info_with_rssi_and_pscan_mode *info;
2780 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002781
Johan Hedberge17acd42011-03-30 23:57:16 +03002782 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002783 bacpy(&data.bdaddr, &info->bdaddr);
2784 data.pscan_rep_mode = info->pscan_rep_mode;
2785 data.pscan_period_mode = info->pscan_period_mode;
2786 data.pscan_mode = info->pscan_mode;
2787 memcpy(data.dev_class, info->dev_class, 3);
2788 data.clock_offset = info->clock_offset;
2789 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002790 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002791
2792 name_known = hci_inquiry_cache_update(hdev, &data,
2793 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002794 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002795 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002796 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002797 }
2798 } else {
2799 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2800
Johan Hedberge17acd42011-03-30 23:57:16 +03002801 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002802 bacpy(&data.bdaddr, &info->bdaddr);
2803 data.pscan_rep_mode = info->pscan_rep_mode;
2804 data.pscan_period_mode = info->pscan_period_mode;
2805 data.pscan_mode = 0x00;
2806 memcpy(data.dev_class, info->dev_class, 3);
2807 data.clock_offset = info->clock_offset;
2808 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002809 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002810 name_known = hci_inquiry_cache_update(hdev, &data,
2811 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002812 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002813 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002814 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002815 }
2816 }
2817
2818 hci_dev_unlock(hdev);
2819}
2820
2821static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2822{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002823 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2824 struct hci_conn *conn;
2825
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002826 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002827
Marcel Holtmann41a96212008-07-14 20:13:48 +02002828 hci_dev_lock(hdev);
2829
2830 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002831 if (!conn)
2832 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002833
Johan Hedbergccd556f2010-11-10 17:11:51 +02002834 if (!ev->status && ev->page == 0x01) {
2835 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002836
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002837 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2838 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002839 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002840
Johan Hedberg58a681e2012-01-16 06:47:28 +02002841 if (ev->features[0] & 0x01)
2842 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002843 }
2844
Johan Hedbergccd556f2010-11-10 17:11:51 +02002845 if (conn->state != BT_CONFIG)
2846 goto unlock;
2847
Johan Hedberg127178d2010-11-18 22:22:29 +02002848 if (!ev->status) {
2849 struct hci_cp_remote_name_req cp;
2850 memset(&cp, 0, sizeof(cp));
2851 bacpy(&cp.bdaddr, &conn->dst);
2852 cp.pscan_rep_mode = 0x02;
2853 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002854 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2855 mgmt_device_connected(hdev, &conn->dst, conn->type,
2856 conn->dst_type, NULL, 0,
2857 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002858
Johan Hedberg127178d2010-11-18 22:22:29 +02002859 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002860 conn->state = BT_CONNECTED;
2861 hci_proto_connect_cfm(conn, ev->status);
2862 hci_conn_put(conn);
2863 }
2864
2865unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002866 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002867}
2868
2869static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2870{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002871 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2872 struct hci_conn *conn;
2873
2874 BT_DBG("%s status %d", hdev->name, ev->status);
2875
2876 hci_dev_lock(hdev);
2877
2878 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002879 if (!conn) {
2880 if (ev->link_type == ESCO_LINK)
2881 goto unlock;
2882
2883 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2884 if (!conn)
2885 goto unlock;
2886
2887 conn->type = SCO_LINK;
2888 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002889
Marcel Holtmann732547f2009-04-19 19:14:14 +02002890 switch (ev->status) {
2891 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002892 conn->handle = __le16_to_cpu(ev->handle);
2893 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002894
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002895 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002896 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002897 break;
2898
Stephen Coe705e5712010-02-16 11:29:44 -05002899 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002900 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002901 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002902 case 0x1f: /* Unspecified error */
2903 if (conn->out && conn->attempt < 2) {
2904 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2905 (hdev->esco_type & EDR_ESCO_MASK);
2906 hci_setup_sync(conn, conn->link->handle);
2907 goto unlock;
2908 }
2909 /* fall through */
2910
2911 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002912 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002913 break;
2914 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002915
2916 hci_proto_connect_cfm(conn, ev->status);
2917 if (ev->status)
2918 hci_conn_del(conn);
2919
2920unlock:
2921 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002922}
2923
2924static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2925{
2926 BT_DBG("%s", hdev->name);
2927}
2928
Marcel Holtmann04837f62006-07-03 10:02:33 +02002929static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2930{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002931 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002932
2933 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002934}
2935
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002936static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2937{
2938 struct inquiry_data data;
2939 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2940 int num_rsp = *((__u8 *) skb->data);
2941
2942 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2943
2944 if (!num_rsp)
2945 return;
2946
2947 hci_dev_lock(hdev);
2948
Johan Hedberge17acd42011-03-30 23:57:16 +03002949 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg561aafb2012-01-04 13:31:59 +02002950 bool name_known;
2951
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002952 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002953 data.pscan_rep_mode = info->pscan_rep_mode;
2954 data.pscan_period_mode = info->pscan_period_mode;
2955 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002956 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002957 data.clock_offset = info->clock_offset;
2958 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002959 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002960
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002961 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002962 name_known = eir_has_data_type(info->data,
2963 sizeof(info->data),
2964 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002965 else
2966 name_known = true;
2967
Johan Hedberg31754052012-01-04 13:39:52 +02002968 name_known = hci_inquiry_cache_update(hdev, &data, name_known);
Johan Hedberg48264f02011-11-09 13:58:58 +02002969 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002970 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002971 !name_known, info->data,
2972 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002973 }
2974
2975 hci_dev_unlock(hdev);
2976}
2977
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002978static inline u8 hci_get_auth_req(struct hci_conn *conn)
2979{
2980 /* If remote requests dedicated bonding follow that lead */
2981 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2982 /* If both remote and local IO capabilities allow MITM
2983 * protection then require it, otherwise don't */
2984 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2985 return 0x02;
2986 else
2987 return 0x03;
2988 }
2989
2990 /* If remote requests no-bonding follow that lead */
2991 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002992 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002993
2994 return conn->auth_type;
2995}
2996
Marcel Holtmann04936842008-07-14 20:13:48 +02002997static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2998{
2999 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3000 struct hci_conn *conn;
3001
3002 BT_DBG("%s", hdev->name);
3003
3004 hci_dev_lock(hdev);
3005
3006 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003007 if (!conn)
3008 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003009
Johan Hedberg03b555e2011-01-04 15:40:05 +02003010 hci_conn_hold(conn);
3011
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003012 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003013 goto unlock;
3014
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003015 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003016 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003017 struct hci_cp_io_capability_reply cp;
3018
3019 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303020 /* Change the IO capability from KeyboardDisplay
3021 * to DisplayYesNo as it is not supported by BT spec. */
3022 cp.capability = (conn->io_capability == 0x04) ?
3023 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003024 conn->auth_type = hci_get_auth_req(conn);
3025 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003026
Johan Hedberg58a681e2012-01-16 06:47:28 +02003027 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003028 hci_find_remote_oob_data(hdev, &conn->dst))
3029 cp.oob_data = 0x01;
3030 else
3031 cp.oob_data = 0x00;
3032
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003033 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3034 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003035 } else {
3036 struct hci_cp_io_capability_neg_reply cp;
3037
3038 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003039 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003040
3041 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3042 sizeof(cp), &cp);
3043 }
3044
3045unlock:
3046 hci_dev_unlock(hdev);
3047}
3048
3049static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3050{
3051 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3052 struct hci_conn *conn;
3053
3054 BT_DBG("%s", hdev->name);
3055
3056 hci_dev_lock(hdev);
3057
3058 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3059 if (!conn)
3060 goto unlock;
3061
Johan Hedberg03b555e2011-01-04 15:40:05 +02003062 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003063 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003064 if (ev->oob_data)
3065 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003066
3067unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003068 hci_dev_unlock(hdev);
3069}
3070
Johan Hedberga5c29682011-02-19 12:05:57 -03003071static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3072 struct sk_buff *skb)
3073{
3074 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003075 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003076 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003077
3078 BT_DBG("%s", hdev->name);
3079
3080 hci_dev_lock(hdev);
3081
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003082 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003083 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003084
Johan Hedberg7a828902011-04-28 11:28:53 -07003085 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3086 if (!conn)
3087 goto unlock;
3088
3089 loc_mitm = (conn->auth_type & 0x01);
3090 rem_mitm = (conn->remote_auth & 0x01);
3091
3092 /* If we require MITM but the remote device can't provide that
3093 * (it has NoInputNoOutput) then reject the confirmation
3094 * request. The only exception is when we're dedicated bonding
3095 * initiators (connect_cfm_cb set) since then we always have the MITM
3096 * bit set. */
3097 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3098 BT_DBG("Rejecting request: remote device can't provide MITM");
3099 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3100 sizeof(ev->bdaddr), &ev->bdaddr);
3101 goto unlock;
3102 }
3103
3104 /* If no side requires MITM protection; auto-accept */
3105 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3106 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003107
3108 /* If we're not the initiators request authorization to
3109 * proceed from user space (mgmt_user_confirm with
3110 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003111 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003112 BT_DBG("Confirming auto-accept as acceptor");
3113 confirm_hint = 1;
3114 goto confirm;
3115 }
3116
Johan Hedberg9f616562011-04-28 11:28:54 -07003117 BT_DBG("Auto-accept of user confirmation with %ums delay",
3118 hdev->auto_accept_delay);
3119
3120 if (hdev->auto_accept_delay > 0) {
3121 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3122 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3123 goto unlock;
3124 }
3125
Johan Hedberg7a828902011-04-28 11:28:53 -07003126 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3127 sizeof(ev->bdaddr), &ev->bdaddr);
3128 goto unlock;
3129 }
3130
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003131confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003132 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003133 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003134
3135unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003136 hci_dev_unlock(hdev);
3137}
3138
Brian Gix1143d452011-11-23 08:28:34 -08003139static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3140 struct sk_buff *skb)
3141{
3142 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3143
3144 BT_DBG("%s", hdev->name);
3145
3146 hci_dev_lock(hdev);
3147
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003148 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003149 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003150
3151 hci_dev_unlock(hdev);
3152}
3153
Marcel Holtmann04936842008-07-14 20:13:48 +02003154static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3155{
3156 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3157 struct hci_conn *conn;
3158
3159 BT_DBG("%s", hdev->name);
3160
3161 hci_dev_lock(hdev);
3162
3163 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003164 if (!conn)
3165 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003166
Johan Hedberg2a611692011-02-19 12:06:00 -03003167 /* To avoid duplicate auth_failed events to user space we check
3168 * the HCI_CONN_AUTH_PEND flag which will be set if we
3169 * initiated the authentication. A traditional auth_complete
3170 * event gets always produced as initiator and is also mapped to
3171 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003172 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003173 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3174 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003175
3176 hci_conn_put(conn);
3177
3178unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003179 hci_dev_unlock(hdev);
3180}
3181
Marcel Holtmann41a96212008-07-14 20:13:48 +02003182static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3183{
3184 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3185 struct inquiry_entry *ie;
3186
3187 BT_DBG("%s", hdev->name);
3188
3189 hci_dev_lock(hdev);
3190
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003191 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3192 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003193 ie->data.ssp_mode = (ev->features[0] & 0x01);
3194
3195 hci_dev_unlock(hdev);
3196}
3197
Szymon Janc2763eda2011-03-22 13:12:22 +01003198static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3199 struct sk_buff *skb)
3200{
3201 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3202 struct oob_data *data;
3203
3204 BT_DBG("%s", hdev->name);
3205
3206 hci_dev_lock(hdev);
3207
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003208 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003209 goto unlock;
3210
Szymon Janc2763eda2011-03-22 13:12:22 +01003211 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3212 if (data) {
3213 struct hci_cp_remote_oob_data_reply cp;
3214
3215 bacpy(&cp.bdaddr, &ev->bdaddr);
3216 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3217 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3218
3219 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3220 &cp);
3221 } else {
3222 struct hci_cp_remote_oob_data_neg_reply cp;
3223
3224 bacpy(&cp.bdaddr, &ev->bdaddr);
3225 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3226 &cp);
3227 }
3228
Szymon Jance1ba1f12011-04-06 13:01:59 +02003229unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003230 hci_dev_unlock(hdev);
3231}
3232
Ville Tervofcd89c02011-02-10 22:38:47 -03003233static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3234{
3235 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3236 struct hci_conn *conn;
3237
3238 BT_DBG("%s status %d", hdev->name, ev->status);
3239
3240 hci_dev_lock(hdev);
3241
3242 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003243 if (!conn) {
3244 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3245 if (!conn) {
3246 BT_ERR("No memory for new connection");
3247 hci_dev_unlock(hdev);
3248 return;
3249 }
Andre Guedes29b79882011-05-31 14:20:54 -03003250
3251 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003252 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003253
3254 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003255 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3256 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003257 hci_proto_connect_cfm(conn, ev->status);
3258 conn->state = BT_CLOSED;
3259 hci_conn_del(conn);
3260 goto unlock;
3261 }
3262
Johan Hedbergb644ba32012-01-17 21:48:47 +02003263 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3264 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3265 conn->dst_type, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003266
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003267 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003268 conn->handle = __le16_to_cpu(ev->handle);
3269 conn->state = BT_CONNECTED;
3270
3271 hci_conn_hold_device(conn);
3272 hci_conn_add_sysfs(conn);
3273
3274 hci_proto_connect_cfm(conn, ev->status);
3275
3276unlock:
3277 hci_dev_unlock(hdev);
3278}
3279
Andre Guedes9aa04c92011-05-26 16:23:51 -03003280static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3281 struct sk_buff *skb)
3282{
Andre Guedese95beb42011-09-26 20:48:35 -03003283 u8 num_reports = skb->data[0];
3284 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003285 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003286
3287 hci_dev_lock(hdev);
3288
Andre Guedese95beb42011-09-26 20:48:35 -03003289 while (num_reports--) {
3290 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003291
Andre Guedes9aa04c92011-05-26 16:23:51 -03003292 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003293
Andre Guedes3c9e9192012-01-10 18:20:50 -03003294 rssi = ev->data[ev->length];
3295 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3296 NULL, rssi, 0, ev->data, ev->length);
3297
Andre Guedese95beb42011-09-26 20:48:35 -03003298 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003299 }
3300
3301 hci_dev_unlock(hdev);
3302}
3303
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003304static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3305 struct sk_buff *skb)
3306{
3307 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3308 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003309 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003310 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003311 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003312
3313 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3314
3315 hci_dev_lock(hdev);
3316
3317 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003318 if (conn == NULL)
3319 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003320
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003321 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3322 if (ltk == NULL)
3323 goto not_found;
3324
3325 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003326 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003327
3328 if (ltk->authenticated)
3329 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003330
3331 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3332
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003333 if (ltk->type & HCI_SMP_STK) {
3334 list_del(&ltk->list);
3335 kfree(ltk);
3336 }
3337
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003338 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003339
3340 return;
3341
3342not_found:
3343 neg.handle = ev->handle;
3344 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3345 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003346}
3347
Ville Tervofcd89c02011-02-10 22:38:47 -03003348static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3349{
3350 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3351
3352 skb_pull(skb, sizeof(*le_ev));
3353
3354 switch (le_ev->subevent) {
3355 case HCI_EV_LE_CONN_COMPLETE:
3356 hci_le_conn_complete_evt(hdev, skb);
3357 break;
3358
Andre Guedes9aa04c92011-05-26 16:23:51 -03003359 case HCI_EV_LE_ADVERTISING_REPORT:
3360 hci_le_adv_report_evt(hdev, skb);
3361 break;
3362
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003363 case HCI_EV_LE_LTK_REQ:
3364 hci_le_ltk_request_evt(hdev, skb);
3365 break;
3366
Ville Tervofcd89c02011-02-10 22:38:47 -03003367 default:
3368 break;
3369 }
3370}
3371
Linus Torvalds1da177e2005-04-16 15:20:36 -07003372void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3373{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003374 struct hci_event_hdr *hdr = (void *) skb->data;
3375 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003376
3377 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3378
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003379 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003380 case HCI_EV_INQUIRY_COMPLETE:
3381 hci_inquiry_complete_evt(hdev, skb);
3382 break;
3383
3384 case HCI_EV_INQUIRY_RESULT:
3385 hci_inquiry_result_evt(hdev, skb);
3386 break;
3387
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003388 case HCI_EV_CONN_COMPLETE:
3389 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003390 break;
3391
Linus Torvalds1da177e2005-04-16 15:20:36 -07003392 case HCI_EV_CONN_REQUEST:
3393 hci_conn_request_evt(hdev, skb);
3394 break;
3395
Linus Torvalds1da177e2005-04-16 15:20:36 -07003396 case HCI_EV_DISCONN_COMPLETE:
3397 hci_disconn_complete_evt(hdev, skb);
3398 break;
3399
Linus Torvalds1da177e2005-04-16 15:20:36 -07003400 case HCI_EV_AUTH_COMPLETE:
3401 hci_auth_complete_evt(hdev, skb);
3402 break;
3403
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003404 case HCI_EV_REMOTE_NAME:
3405 hci_remote_name_evt(hdev, skb);
3406 break;
3407
Linus Torvalds1da177e2005-04-16 15:20:36 -07003408 case HCI_EV_ENCRYPT_CHANGE:
3409 hci_encrypt_change_evt(hdev, skb);
3410 break;
3411
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003412 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3413 hci_change_link_key_complete_evt(hdev, skb);
3414 break;
3415
3416 case HCI_EV_REMOTE_FEATURES:
3417 hci_remote_features_evt(hdev, skb);
3418 break;
3419
3420 case HCI_EV_REMOTE_VERSION:
3421 hci_remote_version_evt(hdev, skb);
3422 break;
3423
3424 case HCI_EV_QOS_SETUP_COMPLETE:
3425 hci_qos_setup_complete_evt(hdev, skb);
3426 break;
3427
3428 case HCI_EV_CMD_COMPLETE:
3429 hci_cmd_complete_evt(hdev, skb);
3430 break;
3431
3432 case HCI_EV_CMD_STATUS:
3433 hci_cmd_status_evt(hdev, skb);
3434 break;
3435
3436 case HCI_EV_ROLE_CHANGE:
3437 hci_role_change_evt(hdev, skb);
3438 break;
3439
3440 case HCI_EV_NUM_COMP_PKTS:
3441 hci_num_comp_pkts_evt(hdev, skb);
3442 break;
3443
3444 case HCI_EV_MODE_CHANGE:
3445 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003446 break;
3447
3448 case HCI_EV_PIN_CODE_REQ:
3449 hci_pin_code_request_evt(hdev, skb);
3450 break;
3451
3452 case HCI_EV_LINK_KEY_REQ:
3453 hci_link_key_request_evt(hdev, skb);
3454 break;
3455
3456 case HCI_EV_LINK_KEY_NOTIFY:
3457 hci_link_key_notify_evt(hdev, skb);
3458 break;
3459
3460 case HCI_EV_CLOCK_OFFSET:
3461 hci_clock_offset_evt(hdev, skb);
3462 break;
3463
Marcel Holtmanna8746412008-07-14 20:13:46 +02003464 case HCI_EV_PKT_TYPE_CHANGE:
3465 hci_pkt_type_change_evt(hdev, skb);
3466 break;
3467
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003468 case HCI_EV_PSCAN_REP_MODE:
3469 hci_pscan_rep_mode_evt(hdev, skb);
3470 break;
3471
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003472 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3473 hci_inquiry_result_with_rssi_evt(hdev, skb);
3474 break;
3475
3476 case HCI_EV_REMOTE_EXT_FEATURES:
3477 hci_remote_ext_features_evt(hdev, skb);
3478 break;
3479
3480 case HCI_EV_SYNC_CONN_COMPLETE:
3481 hci_sync_conn_complete_evt(hdev, skb);
3482 break;
3483
3484 case HCI_EV_SYNC_CONN_CHANGED:
3485 hci_sync_conn_changed_evt(hdev, skb);
3486 break;
3487
Marcel Holtmann04837f62006-07-03 10:02:33 +02003488 case HCI_EV_SNIFF_SUBRATE:
3489 hci_sniff_subrate_evt(hdev, skb);
3490 break;
3491
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003492 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3493 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003494 break;
3495
Marcel Holtmann04936842008-07-14 20:13:48 +02003496 case HCI_EV_IO_CAPA_REQUEST:
3497 hci_io_capa_request_evt(hdev, skb);
3498 break;
3499
Johan Hedberg03b555e2011-01-04 15:40:05 +02003500 case HCI_EV_IO_CAPA_REPLY:
3501 hci_io_capa_reply_evt(hdev, skb);
3502 break;
3503
Johan Hedberga5c29682011-02-19 12:05:57 -03003504 case HCI_EV_USER_CONFIRM_REQUEST:
3505 hci_user_confirm_request_evt(hdev, skb);
3506 break;
3507
Brian Gix1143d452011-11-23 08:28:34 -08003508 case HCI_EV_USER_PASSKEY_REQUEST:
3509 hci_user_passkey_request_evt(hdev, skb);
3510 break;
3511
Marcel Holtmann04936842008-07-14 20:13:48 +02003512 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3513 hci_simple_pair_complete_evt(hdev, skb);
3514 break;
3515
Marcel Holtmann41a96212008-07-14 20:13:48 +02003516 case HCI_EV_REMOTE_HOST_FEATURES:
3517 hci_remote_host_features_evt(hdev, skb);
3518 break;
3519
Ville Tervofcd89c02011-02-10 22:38:47 -03003520 case HCI_EV_LE_META:
3521 hci_le_meta_evt(hdev, skb);
3522 break;
3523
Szymon Janc2763eda2011-03-22 13:12:22 +01003524 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3525 hci_remote_oob_data_request_evt(hdev, skb);
3526 break;
3527
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003528 case HCI_EV_NUM_COMP_BLOCKS:
3529 hci_num_comp_blocks_evt(hdev, skb);
3530 break;
3531
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003532 default:
3533 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003534 break;
3535 }
3536
3537 kfree_skb(skb);
3538 hdev->stat.evt_rx++;
3539}
3540
3541/* Generate internal stack event */
3542void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3543{
3544 struct hci_event_hdr *hdr;
3545 struct hci_ev_stack_internal *ev;
3546 struct sk_buff *skb;
3547
3548 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3549 if (!skb)
3550 return;
3551
3552 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3553 hdr->evt = HCI_EV_STACK_INTERNAL;
3554 hdr->plen = sizeof(*ev) + dlen;
3555
3556 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3557 ev->type = type;
3558 memcpy(ev->data, data, dlen);
3559
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003560 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003561 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003562
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003563 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003564 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003565 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003566 kfree_skb(skb);
3567}
Andre Guedese6100a22011-06-30 19:20:54 -03003568
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003569module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003570MODULE_PARM_DESC(enable_le, "Enable LE support");