blob: 75b03fc7800256d80cef8dfbc7d26ff1219e7172 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <net/sock.h>
39
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020040#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <asm/unaligned.h>
42
43#include <net/bluetooth/bluetooth.h>
44#include <net/bluetooth/hci_core.h>
45
Linus Torvalds1da177e2005-04-16 15:20:36 -070046/* Handle HCI Event packets */
47
Marcel Holtmanna9de9242007-10-20 13:33:56 +020048static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070049{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020050 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
Andre Guedese6d465c2011-11-09 17:14:26 -030054 if (status) {
55 hci_dev_lock(hdev);
56 mgmt_stop_discovery_failed(hdev, status);
57 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020058 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030059 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
Andre Guedes89352e72011-11-04 14:16:53 -030061 clear_bit(HCI_INQUIRY, &hdev->flags);
62
Johan Hedberg56e5cb82011-11-08 20:40:16 +020063 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020064 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020065 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010066
Johan Hedberg23bb5762010-12-21 23:01:27 +020067 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010068
Marcel Holtmanna9de9242007-10-20 13:33:56 +020069 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070070}
71
Andre Guedes4d934832012-03-21 00:03:35 -030072static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
73{
74 __u8 status = *((__u8 *) skb->data);
75
76 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030077
78 if (status)
79 return;
80
81 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030082}
83
Marcel Holtmanna9de9242007-10-20 13:33:56 +020084static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070085{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020086 __u8 status = *((__u8 *) skb->data);
87
88 BT_DBG("%s status 0x%x", hdev->name, status);
89
90 if (status)
91 return;
92
Andre Guedesae854a72012-03-21 00:03:36 -030093 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
94
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 hci_conn_check_pending(hdev);
96}
97
Gustavo Padovan807deac2012-05-17 00:36:24 -030098static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
99 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100{
101 BT_DBG("%s", hdev->name);
102}
103
104static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
105{
106 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200109 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200111 if (rp->status)
112 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200114 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200116 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
117 if (conn) {
118 if (rp->role)
119 conn->link_mode &= ~HCI_LM_MASTER;
120 else
121 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200123
124 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125}
126
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200127static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
128{
129 struct hci_rp_read_link_policy *rp = (void *) skb->data;
130 struct hci_conn *conn;
131
132 BT_DBG("%s status 0x%x", hdev->name, rp->status);
133
134 if (rp->status)
135 return;
136
137 hci_dev_lock(hdev);
138
139 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
140 if (conn)
141 conn->link_policy = __le16_to_cpu(rp->policy);
142
143 hci_dev_unlock(hdev);
144}
145
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200146static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200148 struct hci_rp_write_link_policy *rp = (void *) skb->data;
149 struct hci_conn *conn;
150 void *sent;
151
152 BT_DBG("%s status 0x%x", hdev->name, rp->status);
153
154 if (rp->status)
155 return;
156
157 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
158 if (!sent)
159 return;
160
161 hci_dev_lock(hdev);
162
163 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200164 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700165 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200166
167 hci_dev_unlock(hdev);
168}
169
Gustavo Padovan807deac2012-05-17 00:36:24 -0300170static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
171 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200172{
173 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
174
175 BT_DBG("%s status 0x%x", hdev->name, rp->status);
176
177 if (rp->status)
178 return;
179
180 hdev->link_policy = __le16_to_cpu(rp->policy);
181}
182
Gustavo Padovan807deac2012-05-17 00:36:24 -0300183static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
184 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200185{
186 __u8 status = *((__u8 *) skb->data);
187 void *sent;
188
189 BT_DBG("%s status 0x%x", hdev->name, status);
190
191 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
192 if (!sent)
193 return;
194
195 if (!status)
196 hdev->link_policy = get_unaligned_le16(sent);
197
Johan Hedberg23bb5762010-12-21 23:01:27 +0200198 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200199}
200
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200201static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
202{
203 __u8 status = *((__u8 *) skb->data);
204
205 BT_DBG("%s status 0x%x", hdev->name, status);
206
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300207 clear_bit(HCI_RESET, &hdev->flags);
208
Johan Hedberg23bb5762010-12-21 23:01:27 +0200209 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300210
Johan Hedberga297e972012-02-21 17:55:47 +0200211 /* Reset all non-persistent flags */
Andre Guedesae854a72012-03-21 00:03:36 -0300212 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN) | BIT(HCI_PENDING_CLASS) |
213 BIT(HCI_PERIODIC_INQ));
Andre Guedes69775ff2012-02-23 16:50:05 +0200214
215 hdev->discovery.state = DISCOVERY_STOPPED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200216}
217
218static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
219{
220 __u8 status = *((__u8 *) skb->data);
221 void *sent;
222
223 BT_DBG("%s status 0x%x", hdev->name, status);
224
225 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
226 if (!sent)
227 return;
228
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200229 hci_dev_lock(hdev);
230
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200231 if (test_bit(HCI_MGMT, &hdev->dev_flags))
232 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200233 else if (!status)
234 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200235
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200236 hci_dev_unlock(hdev);
Johan Hedberg3159d382012-02-24 13:47:56 +0200237
238 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200239}
240
241static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
242{
243 struct hci_rp_read_local_name *rp = (void *) skb->data;
244
245 BT_DBG("%s status 0x%x", hdev->name, rp->status);
246
247 if (rp->status)
248 return;
249
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200250 if (test_bit(HCI_SETUP, &hdev->dev_flags))
251 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200252}
253
254static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
255{
256 __u8 status = *((__u8 *) skb->data);
257 void *sent;
258
259 BT_DBG("%s status 0x%x", hdev->name, status);
260
261 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
262 if (!sent)
263 return;
264
265 if (!status) {
266 __u8 param = *((__u8 *) sent);
267
268 if (param == AUTH_ENABLED)
269 set_bit(HCI_AUTH, &hdev->flags);
270 else
271 clear_bit(HCI_AUTH, &hdev->flags);
272 }
273
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200274 if (test_bit(HCI_MGMT, &hdev->dev_flags))
275 mgmt_auth_enable_complete(hdev, status);
276
Johan Hedberg23bb5762010-12-21 23:01:27 +0200277 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200278}
279
280static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
281{
282 __u8 status = *((__u8 *) skb->data);
283 void *sent;
284
285 BT_DBG("%s status 0x%x", hdev->name, status);
286
287 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
288 if (!sent)
289 return;
290
291 if (!status) {
292 __u8 param = *((__u8 *) sent);
293
294 if (param)
295 set_bit(HCI_ENCRYPT, &hdev->flags);
296 else
297 clear_bit(HCI_ENCRYPT, &hdev->flags);
298 }
299
Johan Hedberg23bb5762010-12-21 23:01:27 +0200300 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200301}
302
303static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
304{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200305 __u8 param, status = *((__u8 *) skb->data);
306 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200307 void *sent;
308
309 BT_DBG("%s status 0x%x", hdev->name, status);
310
311 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
312 if (!sent)
313 return;
314
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200315 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200316
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200317 hci_dev_lock(hdev);
318
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200319 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200320 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200321 hdev->discov_timeout = 0;
322 goto done;
323 }
324
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200325 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
326 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200327
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200328 if (param & SCAN_INQUIRY) {
329 set_bit(HCI_ISCAN, &hdev->flags);
330 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200331 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200332 if (hdev->discov_timeout > 0) {
333 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
334 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300335 to);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200336 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200337 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200338 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200339
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200340 if (param & SCAN_PAGE) {
341 set_bit(HCI_PSCAN, &hdev->flags);
342 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200343 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200344 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200345 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200346
347done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200348 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200349 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200350}
351
352static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
353{
354 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
355
356 BT_DBG("%s status 0x%x", hdev->name, rp->status);
357
358 if (rp->status)
359 return;
360
361 memcpy(hdev->dev_class, rp->dev_class, 3);
362
363 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300364 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200365}
366
367static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
368{
369 __u8 status = *((__u8 *) skb->data);
370 void *sent;
371
372 BT_DBG("%s status 0x%x", hdev->name, status);
373
374 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
375 if (!sent)
376 return;
377
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100378 hci_dev_lock(hdev);
379
380 if (status == 0)
381 memcpy(hdev->dev_class, sent, 3);
382
383 if (test_bit(HCI_MGMT, &hdev->dev_flags))
384 mgmt_set_class_of_dev_complete(hdev, sent, status);
385
386 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200387}
388
389static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
390{
391 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200393
394 BT_DBG("%s status 0x%x", hdev->name, rp->status);
395
396 if (rp->status)
397 return;
398
399 setting = __le16_to_cpu(rp->voice_setting);
400
Marcel Holtmannf383f272008-07-14 20:13:47 +0200401 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200402 return;
403
404 hdev->voice_setting = setting;
405
406 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
407
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200408 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200409 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200410}
411
412static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
413{
414 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200415 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 void *sent;
417
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200418 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
Marcel Holtmannf383f272008-07-14 20:13:47 +0200420 if (status)
421 return;
422
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200423 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
424 if (!sent)
425 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
Marcel Holtmannf383f272008-07-14 20:13:47 +0200427 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428
Marcel Holtmannf383f272008-07-14 20:13:47 +0200429 if (hdev->voice_setting == setting)
430 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431
Marcel Holtmannf383f272008-07-14 20:13:47 +0200432 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433
Marcel Holtmannf383f272008-07-14 20:13:47 +0200434 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
435
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200436 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200437 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438}
439
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200440static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200442 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200444 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445
Johan Hedberg23bb5762010-12-21 23:01:27 +0200446 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447}
448
Marcel Holtmann333140b2008-07-14 20:13:48 +0200449static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
450{
451 __u8 status = *((__u8 *) skb->data);
452 void *sent;
453
454 BT_DBG("%s status 0x%x", hdev->name, status);
455
Marcel Holtmann333140b2008-07-14 20:13:48 +0200456 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
457 if (!sent)
458 return;
459
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200460 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200461 mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status);
462 else if (!status) {
463 if (*((u8 *) sent))
464 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
465 else
466 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
467 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200468}
469
Johan Hedbergd5859e22011-01-25 01:19:58 +0200470static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
471{
472 if (hdev->features[6] & LMP_EXT_INQ)
473 return 2;
474
475 if (hdev->features[3] & LMP_RSSI_INQ)
476 return 1;
477
478 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -0300479 hdev->lmp_subver == 0x0757)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200480 return 1;
481
482 if (hdev->manufacturer == 15) {
483 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
484 return 1;
485 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
486 return 1;
487 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
488 return 1;
489 }
490
491 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -0300492 hdev->lmp_subver == 0x1805)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200493 return 1;
494
495 return 0;
496}
497
498static void hci_setup_inquiry_mode(struct hci_dev *hdev)
499{
500 u8 mode;
501
502 mode = hci_get_inquiry_mode(hdev);
503
504 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
505}
506
507static void hci_setup_event_mask(struct hci_dev *hdev)
508{
509 /* The second byte is 0xff instead of 0x9f (two reserved bits
510 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
511 * command otherwise */
512 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
513
Ville Tervo6de6c182011-05-27 11:16:21 +0300514 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
515 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200516 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300517 return;
518
519 events[4] |= 0x01; /* Flow Specification Complete */
520 events[4] |= 0x02; /* Inquiry Result with RSSI */
521 events[4] |= 0x04; /* Read Remote Extended Features Complete */
522 events[5] |= 0x08; /* Synchronous Connection Complete */
523 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200524
525 if (hdev->features[3] & LMP_RSSI_INQ)
Johan Hedberga24299e2012-04-26 09:47:46 +0300526 events[4] |= 0x02; /* Inquiry Result with RSSI */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200527
528 if (hdev->features[5] & LMP_SNIFF_SUBR)
529 events[5] |= 0x20; /* Sniff Subrating */
530
531 if (hdev->features[5] & LMP_PAUSE_ENC)
532 events[5] |= 0x80; /* Encryption Key Refresh Complete */
533
534 if (hdev->features[6] & LMP_EXT_INQ)
535 events[5] |= 0x40; /* Extended Inquiry Result */
536
537 if (hdev->features[6] & LMP_NO_FLUSH)
538 events[7] |= 0x01; /* Enhanced Flush Complete */
539
540 if (hdev->features[7] & LMP_LSTO)
541 events[6] |= 0x80; /* Link Supervision Timeout Changed */
542
543 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
544 events[6] |= 0x01; /* IO Capability Request */
545 events[6] |= 0x02; /* IO Capability Response */
546 events[6] |= 0x04; /* User Confirmation Request */
547 events[6] |= 0x08; /* User Passkey Request */
548 events[6] |= 0x10; /* Remote OOB Data Request */
549 events[6] |= 0x20; /* Simple Pairing Complete */
550 events[7] |= 0x04; /* User Passkey Notification */
551 events[7] |= 0x08; /* Keypress Notification */
552 events[7] |= 0x10; /* Remote Host Supported
553 * Features Notification */
554 }
555
556 if (hdev->features[4] & LMP_LE)
557 events[7] |= 0x20; /* LE Meta-Event */
558
559 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
560}
561
562static void hci_setup(struct hci_dev *hdev)
563{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200564 if (hdev->dev_type != HCI_BREDR)
565 return;
566
Johan Hedbergd5859e22011-01-25 01:19:58 +0200567 hci_setup_event_mask(hdev);
568
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200569 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200570 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
571
Johan Hedberg54d04db2012-02-22 15:47:48 +0200572 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
573 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
574 u8 mode = 0x01;
575 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300576 sizeof(mode), &mode);
Johan Hedberg54d04db2012-02-22 15:47:48 +0200577 } else {
578 struct hci_cp_write_eir cp;
579
580 memset(hdev->eir, 0, sizeof(hdev->eir));
581 memset(&cp, 0, sizeof(cp));
582
583 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
584 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200585 }
586
587 if (hdev->features[3] & LMP_RSSI_INQ)
588 hci_setup_inquiry_mode(hdev);
589
590 if (hdev->features[7] & LMP_INQ_TX_PWR)
591 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300592
593 if (hdev->features[7] & LMP_EXTFEATURES) {
594 struct hci_cp_read_local_ext_features cp;
595
596 cp.page = 0x01;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300597 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp),
598 &cp);
Andre Guedes971e3a42011-06-30 19:20:52 -0300599 }
Andre Guedese6100a22011-06-30 19:20:54 -0300600
Johan Hedberg47990ea2012-02-22 11:58:37 +0200601 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
602 u8 enable = 1;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300603 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
604 &enable);
Johan Hedberg47990ea2012-02-22 11:58:37 +0200605 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200606}
607
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200608static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
609{
610 struct hci_rp_read_local_version *rp = (void *) skb->data;
611
612 BT_DBG("%s status 0x%x", hdev->name, rp->status);
613
614 if (rp->status)
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200615 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200616
617 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200618 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200619 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200620 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200621 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200622
623 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300624 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200625
626 if (test_bit(HCI_INIT, &hdev->flags))
627 hci_setup(hdev);
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200628
629done:
630 hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200631}
632
633static void hci_setup_link_policy(struct hci_dev *hdev)
634{
Andrei Emeltchenko035100c2012-03-12 15:59:32 +0200635 struct hci_cp_write_def_link_policy cp;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200636 u16 link_policy = 0;
637
638 if (hdev->features[0] & LMP_RSWITCH)
639 link_policy |= HCI_LP_RSWITCH;
640 if (hdev->features[0] & LMP_HOLD)
641 link_policy |= HCI_LP_HOLD;
642 if (hdev->features[0] & LMP_SNIFF)
643 link_policy |= HCI_LP_SNIFF;
644 if (hdev->features[1] & LMP_PARK)
645 link_policy |= HCI_LP_PARK;
646
Andrei Emeltchenko035100c2012-03-12 15:59:32 +0200647 cp.policy = cpu_to_le16(link_policy);
648 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200649}
650
651static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
652{
653 struct hci_rp_read_local_commands *rp = (void *) skb->data;
654
655 BT_DBG("%s status 0x%x", hdev->name, rp->status);
656
657 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200658 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200659
660 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200661
662 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
663 hci_setup_link_policy(hdev);
664
665done:
666 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200667}
668
669static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
670{
671 struct hci_rp_read_local_features *rp = (void *) skb->data;
672
673 BT_DBG("%s status 0x%x", hdev->name, rp->status);
674
675 if (rp->status)
676 return;
677
678 memcpy(hdev->features, rp->features, 8);
679
680 /* Adjust default settings according to features
681 * supported by device. */
682
683 if (hdev->features[0] & LMP_3SLOT)
684 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
685
686 if (hdev->features[0] & LMP_5SLOT)
687 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
688
689 if (hdev->features[1] & LMP_HV2) {
690 hdev->pkt_type |= (HCI_HV2);
691 hdev->esco_type |= (ESCO_HV2);
692 }
693
694 if (hdev->features[1] & LMP_HV3) {
695 hdev->pkt_type |= (HCI_HV3);
696 hdev->esco_type |= (ESCO_HV3);
697 }
698
699 if (hdev->features[3] & LMP_ESCO)
700 hdev->esco_type |= (ESCO_EV3);
701
702 if (hdev->features[4] & LMP_EV4)
703 hdev->esco_type |= (ESCO_EV4);
704
705 if (hdev->features[4] & LMP_EV5)
706 hdev->esco_type |= (ESCO_EV5);
707
Marcel Holtmannefc76882009-02-06 09:13:37 +0100708 if (hdev->features[5] & LMP_EDR_ESCO_2M)
709 hdev->esco_type |= (ESCO_2EV3);
710
711 if (hdev->features[5] & LMP_EDR_ESCO_3M)
712 hdev->esco_type |= (ESCO_3EV3);
713
714 if (hdev->features[5] & LMP_EDR_3S_ESCO)
715 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
716
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200717 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300718 hdev->features[0], hdev->features[1],
719 hdev->features[2], hdev->features[3],
720 hdev->features[4], hdev->features[5],
721 hdev->features[6], hdev->features[7]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200722}
723
Johan Hedberg8f984df2012-02-28 01:07:22 +0200724static void hci_set_le_support(struct hci_dev *hdev)
725{
726 struct hci_cp_write_le_host_supported cp;
727
728 memset(&cp, 0, sizeof(cp));
729
Marcel Holtmann9d428202012-05-03 07:12:31 +0200730 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
Johan Hedberg8f984df2012-02-28 01:07:22 +0200731 cp.le = 1;
732 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
733 }
734
735 if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300736 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
737 &cp);
Johan Hedberg8f984df2012-02-28 01:07:22 +0200738}
739
Andre Guedes971e3a42011-06-30 19:20:52 -0300740static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300741 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300742{
743 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
744
745 BT_DBG("%s status 0x%x", hdev->name, rp->status);
746
747 if (rp->status)
Johan Hedberg8f984df2012-02-28 01:07:22 +0200748 goto done;
Andre Guedes971e3a42011-06-30 19:20:52 -0300749
Andre Guedesb5b32b62011-12-30 10:34:04 -0300750 switch (rp->page) {
751 case 0:
752 memcpy(hdev->features, rp->features, 8);
753 break;
754 case 1:
755 memcpy(hdev->host_features, rp->features, 8);
756 break;
757 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300758
Johan Hedberg8f984df2012-02-28 01:07:22 +0200759 if (test_bit(HCI_INIT, &hdev->flags) && hdev->features[4] & LMP_LE)
760 hci_set_le_support(hdev);
761
762done:
Andre Guedes971e3a42011-06-30 19:20:52 -0300763 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
764}
765
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200766static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300767 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200768{
769 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
770
771 BT_DBG("%s status 0x%x", hdev->name, rp->status);
772
773 if (rp->status)
774 return;
775
776 hdev->flow_ctl_mode = rp->mode;
777
778 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
779}
780
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200781static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
782{
783 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
784
785 BT_DBG("%s status 0x%x", hdev->name, rp->status);
786
787 if (rp->status)
788 return;
789
790 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
791 hdev->sco_mtu = rp->sco_mtu;
792 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
793 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
794
795 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
796 hdev->sco_mtu = 64;
797 hdev->sco_pkts = 8;
798 }
799
800 hdev->acl_cnt = hdev->acl_pkts;
801 hdev->sco_cnt = hdev->sco_pkts;
802
Gustavo Padovan807deac2012-05-17 00:36:24 -0300803 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
804 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200805}
806
807static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
808{
809 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
810
811 BT_DBG("%s status 0x%x", hdev->name, rp->status);
812
813 if (!rp->status)
814 bacpy(&hdev->bdaddr, &rp->bdaddr);
815
Johan Hedberg23bb5762010-12-21 23:01:27 +0200816 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
817}
818
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200819static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300820 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200821{
822 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
823
824 BT_DBG("%s status 0x%x", hdev->name, rp->status);
825
826 if (rp->status)
827 return;
828
829 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
830 hdev->block_len = __le16_to_cpu(rp->block_len);
831 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
832
833 hdev->block_cnt = hdev->num_blocks;
834
835 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300836 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200837
838 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
839}
840
Johan Hedberg23bb5762010-12-21 23:01:27 +0200841static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
842{
843 __u8 status = *((__u8 *) skb->data);
844
845 BT_DBG("%s status 0x%x", hdev->name, status);
846
847 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200848}
849
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300850static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300851 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300852{
853 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
854
855 BT_DBG("%s status 0x%x", hdev->name, rp->status);
856
857 if (rp->status)
858 return;
859
860 hdev->amp_status = rp->amp_status;
861 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
862 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
863 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
864 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
865 hdev->amp_type = rp->amp_type;
866 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
867 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
868 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
869 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
870
871 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
872}
873
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200874static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300875 struct sk_buff *skb)
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200876{
877 __u8 status = *((__u8 *) skb->data);
878
879 BT_DBG("%s status 0x%x", hdev->name, status);
880
881 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
882}
883
Johan Hedbergd5859e22011-01-25 01:19:58 +0200884static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
885{
886 __u8 status = *((__u8 *) skb->data);
887
888 BT_DBG("%s status 0x%x", hdev->name, status);
889
890 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
891}
892
893static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300894 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200895{
896 __u8 status = *((__u8 *) skb->data);
897
898 BT_DBG("%s status 0x%x", hdev->name, status);
899
900 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
901}
902
903static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300904 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200905{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700906 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200907
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700908 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200909
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700910 if (!rp->status)
911 hdev->inq_tx_power = rp->tx_power;
912
913 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200914}
915
916static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
917{
918 __u8 status = *((__u8 *) skb->data);
919
920 BT_DBG("%s status 0x%x", hdev->name, status);
921
922 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
923}
924
Johan Hedberg980e1a52011-01-22 06:10:07 +0200925static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
926{
927 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
928 struct hci_cp_pin_code_reply *cp;
929 struct hci_conn *conn;
930
931 BT_DBG("%s status 0x%x", hdev->name, rp->status);
932
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200933 hci_dev_lock(hdev);
934
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200935 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200936 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200937
938 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200939 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200940
941 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
942 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200943 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200944
945 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
946 if (conn)
947 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200948
949unlock:
950 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200951}
952
953static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
954{
955 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
956
957 BT_DBG("%s status 0x%x", hdev->name, rp->status);
958
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200959 hci_dev_lock(hdev);
960
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200961 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200962 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300963 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200964
965 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200966}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200967
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300968static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
969 struct sk_buff *skb)
970{
971 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
972
973 BT_DBG("%s status 0x%x", hdev->name, rp->status);
974
975 if (rp->status)
976 return;
977
978 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
979 hdev->le_pkts = rp->le_max_pkt;
980
981 hdev->le_cnt = hdev->le_pkts;
982
983 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
984
985 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
986}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200987
Johan Hedberga5c29682011-02-19 12:05:57 -0300988static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
989{
990 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
991
992 BT_DBG("%s status 0x%x", hdev->name, rp->status);
993
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200994 hci_dev_lock(hdev);
995
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200996 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300997 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
998 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200999
1000 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -03001001}
1002
1003static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001004 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03001005{
1006 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1007
1008 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1009
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001010 hci_dev_lock(hdev);
1011
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001012 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001013 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001014 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001015
1016 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -03001017}
1018
Brian Gix1143d452011-11-23 08:28:34 -08001019static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
1020{
1021 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1022
1023 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1024
1025 hci_dev_lock(hdev);
1026
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001027 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001028 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001029 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001030
1031 hci_dev_unlock(hdev);
1032}
1033
1034static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001035 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08001036{
1037 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1038
1039 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1040
1041 hci_dev_lock(hdev);
1042
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001043 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001044 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001045 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001046
1047 hci_dev_unlock(hdev);
1048}
1049
Szymon Jancc35938b2011-03-22 13:12:21 +01001050static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001051 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +01001052{
1053 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1054
1055 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1056
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001057 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001058 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001059 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001060 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001061}
1062
Andre Guedes07f7fa52011-12-02 21:13:31 +09001063static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1064{
1065 __u8 status = *((__u8 *) skb->data);
1066
1067 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001068
1069 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001070
1071 if (status) {
1072 hci_dev_lock(hdev);
1073 mgmt_start_discovery_failed(hdev, status);
1074 hci_dev_unlock(hdev);
1075 return;
1076 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001077}
1078
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001079static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001080 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001081{
1082 struct hci_cp_le_set_scan_enable *cp;
1083 __u8 status = *((__u8 *) skb->data);
1084
1085 BT_DBG("%s status 0x%x", hdev->name, status);
1086
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001087 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1088 if (!cp)
1089 return;
1090
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001091 switch (cp->enable) {
1092 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001093 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1094
Andre Guedes3fd24152012-02-03 17:48:01 -03001095 if (status) {
1096 hci_dev_lock(hdev);
1097 mgmt_start_discovery_failed(hdev, status);
1098 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001099 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001100 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001101
Andre Guedesd23264a2011-11-25 20:53:38 -03001102 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1103
Andre Guedesa8f13c82011-09-09 18:56:24 -03001104 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001105 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001106 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001107 break;
1108
1109 case LE_SCANNING_DISABLED:
Andre Guedesc9ecc482012-03-15 16:52:08 -03001110 if (status) {
1111 hci_dev_lock(hdev);
1112 mgmt_stop_discovery_failed(hdev, status);
1113 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001114 return;
Andre Guedesc9ecc482012-03-15 16:52:08 -03001115 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001116
Andre Guedesd23264a2011-11-25 20:53:38 -03001117 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1118
Andre Guedesbc3dd332012-03-06 19:37:06 -03001119 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
1120 hdev->discovery.state == DISCOVERY_FINDING) {
Andre Guedes5e0452c2012-02-17 20:39:38 -03001121 mgmt_interleaved_discovery(hdev);
1122 } else {
1123 hci_dev_lock(hdev);
1124 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1125 hci_dev_unlock(hdev);
1126 }
1127
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001128 break;
1129
1130 default:
1131 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1132 break;
Andre Guedes35815082011-05-26 16:23:53 -03001133 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001134}
1135
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001136static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1137{
1138 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1139
1140 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1141
1142 if (rp->status)
1143 return;
1144
1145 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1146}
1147
1148static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1149{
1150 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1151
1152 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1153
1154 if (rp->status)
1155 return;
1156
1157 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1158}
1159
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001160static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1161 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001162{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001163 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001164 __u8 status = *((__u8 *) skb->data);
1165
1166 BT_DBG("%s status 0x%x", hdev->name, status);
1167
Johan Hedberg06199cf2012-02-22 16:37:11 +02001168 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001169 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001170 return;
1171
Johan Hedberg8f984df2012-02-28 01:07:22 +02001172 if (!status) {
1173 if (sent->le)
1174 hdev->host_features[0] |= LMP_HOST_LE;
1175 else
1176 hdev->host_features[0] &= ~LMP_HOST_LE;
1177 }
1178
1179 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001180 !test_bit(HCI_INIT, &hdev->flags))
Johan Hedberg8f984df2012-02-28 01:07:22 +02001181 mgmt_le_enable_complete(hdev, sent->le, status);
1182
1183 hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001184}
1185
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001186static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001187{
1188 BT_DBG("%s status 0x%x", hdev->name, status);
1189
1190 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001191 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001192 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001193 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001194 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001195 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001196 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001197 return;
1198 }
1199
Andre Guedes89352e72011-11-04 14:16:53 -03001200 set_bit(HCI_INQUIRY, &hdev->flags);
1201
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001202 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001203 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001204 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001205}
1206
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001207static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001209 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001212 BT_DBG("%s status 0x%x", hdev->name, status);
1213
1214 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 if (!cp)
1216 return;
1217
1218 hci_dev_lock(hdev);
1219
1220 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1221
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001222 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223
1224 if (status) {
1225 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001226 if (status != 0x0c || conn->attempt > 2) {
1227 conn->state = BT_CLOSED;
1228 hci_proto_connect_cfm(conn, status);
1229 hci_conn_del(conn);
1230 } else
1231 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 }
1233 } else {
1234 if (!conn) {
1235 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1236 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001237 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 conn->link_mode |= HCI_LM_MASTER;
1239 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001240 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 }
1242 }
1243
1244 hci_dev_unlock(hdev);
1245}
1246
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001247static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001249 struct hci_cp_add_sco *cp;
1250 struct hci_conn *acl, *sco;
1251 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001253 BT_DBG("%s status 0x%x", hdev->name, status);
1254
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001255 if (!status)
1256 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001258 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1259 if (!cp)
1260 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001262 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001264 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001265
1266 hci_dev_lock(hdev);
1267
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001268 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001269 if (acl) {
1270 sco = acl->link;
1271 if (sco) {
1272 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001273
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001274 hci_proto_connect_cfm(sco, status);
1275 hci_conn_del(sco);
1276 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001277 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001278
1279 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001280}
1281
Marcel Holtmannf8558552008-07-14 20:13:49 +02001282static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1283{
1284 struct hci_cp_auth_requested *cp;
1285 struct hci_conn *conn;
1286
1287 BT_DBG("%s status 0x%x", hdev->name, status);
1288
1289 if (!status)
1290 return;
1291
1292 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1293 if (!cp)
1294 return;
1295
1296 hci_dev_lock(hdev);
1297
1298 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1299 if (conn) {
1300 if (conn->state == BT_CONFIG) {
1301 hci_proto_connect_cfm(conn, status);
1302 hci_conn_put(conn);
1303 }
1304 }
1305
1306 hci_dev_unlock(hdev);
1307}
1308
1309static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1310{
1311 struct hci_cp_set_conn_encrypt *cp;
1312 struct hci_conn *conn;
1313
1314 BT_DBG("%s status 0x%x", hdev->name, status);
1315
1316 if (!status)
1317 return;
1318
1319 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1320 if (!cp)
1321 return;
1322
1323 hci_dev_lock(hdev);
1324
1325 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1326 if (conn) {
1327 if (conn->state == BT_CONFIG) {
1328 hci_proto_connect_cfm(conn, status);
1329 hci_conn_put(conn);
1330 }
1331 }
1332
1333 hci_dev_unlock(hdev);
1334}
1335
Johan Hedberg127178d2010-11-18 22:22:29 +02001336static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001337 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001338{
Johan Hedberg392599b2010-11-18 22:22:28 +02001339 if (conn->state != BT_CONFIG || !conn->out)
1340 return 0;
1341
Johan Hedberg765c2a92011-01-19 12:06:52 +05301342 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001343 return 0;
1344
1345 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001346 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001347 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1348 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001349 return 0;
1350
Johan Hedberg392599b2010-11-18 22:22:28 +02001351 return 1;
1352}
1353
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001354static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001355 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001356{
1357 struct hci_cp_remote_name_req cp;
1358
1359 memset(&cp, 0, sizeof(cp));
1360
1361 bacpy(&cp.bdaddr, &e->data.bdaddr);
1362 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1363 cp.pscan_mode = e->data.pscan_mode;
1364 cp.clock_offset = e->data.clock_offset;
1365
1366 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1367}
1368
Johan Hedbergb644ba32012-01-17 21:48:47 +02001369static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001370{
1371 struct discovery_state *discov = &hdev->discovery;
1372 struct inquiry_entry *e;
1373
Johan Hedbergb644ba32012-01-17 21:48:47 +02001374 if (list_empty(&discov->resolve))
1375 return false;
1376
1377 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1378 if (hci_resolve_name(hdev, e) == 0) {
1379 e->name_state = NAME_PENDING;
1380 return true;
1381 }
1382
1383 return false;
1384}
1385
1386static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001387 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001388{
1389 struct discovery_state *discov = &hdev->discovery;
1390 struct inquiry_entry *e;
1391
1392 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001393 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1394 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001395
1396 if (discov->state == DISCOVERY_STOPPED)
1397 return;
1398
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001399 if (discov->state == DISCOVERY_STOPPING)
1400 goto discov_complete;
1401
1402 if (discov->state != DISCOVERY_RESOLVING)
1403 return;
1404
1405 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1406 if (e) {
1407 e->name_state = NAME_KNOWN;
1408 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001409 if (name)
1410 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001411 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001412 }
1413
Johan Hedbergb644ba32012-01-17 21:48:47 +02001414 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001415 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001416
1417discov_complete:
1418 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1419}
1420
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001421static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1422{
Johan Hedberg127178d2010-11-18 22:22:29 +02001423 struct hci_cp_remote_name_req *cp;
1424 struct hci_conn *conn;
1425
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001426 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001427
1428 /* If successful wait for the name req complete event before
1429 * checking for the need to do authentication */
1430 if (!status)
1431 return;
1432
1433 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1434 if (!cp)
1435 return;
1436
1437 hci_dev_lock(hdev);
1438
1439 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001440
1441 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1442 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1443
Johan Hedberg79c6c702011-04-28 11:28:55 -07001444 if (!conn)
1445 goto unlock;
1446
1447 if (!hci_outgoing_auth_needed(hdev, conn))
1448 goto unlock;
1449
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001450 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001451 struct hci_cp_auth_requested cp;
1452 cp.handle = __cpu_to_le16(conn->handle);
1453 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1454 }
1455
Johan Hedberg79c6c702011-04-28 11:28:55 -07001456unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001457 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001458}
1459
Marcel Holtmann769be972008-07-14 20:13:49 +02001460static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1461{
1462 struct hci_cp_read_remote_features *cp;
1463 struct hci_conn *conn;
1464
1465 BT_DBG("%s status 0x%x", hdev->name, status);
1466
1467 if (!status)
1468 return;
1469
1470 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1471 if (!cp)
1472 return;
1473
1474 hci_dev_lock(hdev);
1475
1476 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1477 if (conn) {
1478 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001479 hci_proto_connect_cfm(conn, status);
1480 hci_conn_put(conn);
1481 }
1482 }
1483
1484 hci_dev_unlock(hdev);
1485}
1486
1487static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1488{
1489 struct hci_cp_read_remote_ext_features *cp;
1490 struct hci_conn *conn;
1491
1492 BT_DBG("%s status 0x%x", hdev->name, status);
1493
1494 if (!status)
1495 return;
1496
1497 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1498 if (!cp)
1499 return;
1500
1501 hci_dev_lock(hdev);
1502
1503 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1504 if (conn) {
1505 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001506 hci_proto_connect_cfm(conn, status);
1507 hci_conn_put(conn);
1508 }
1509 }
1510
1511 hci_dev_unlock(hdev);
1512}
1513
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001514static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1515{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001516 struct hci_cp_setup_sync_conn *cp;
1517 struct hci_conn *acl, *sco;
1518 __u16 handle;
1519
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001520 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001521
1522 if (!status)
1523 return;
1524
1525 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1526 if (!cp)
1527 return;
1528
1529 handle = __le16_to_cpu(cp->handle);
1530
1531 BT_DBG("%s handle %d", hdev->name, handle);
1532
1533 hci_dev_lock(hdev);
1534
1535 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001536 if (acl) {
1537 sco = acl->link;
1538 if (sco) {
1539 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001540
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001541 hci_proto_connect_cfm(sco, status);
1542 hci_conn_del(sco);
1543 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001544 }
1545
1546 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001547}
1548
1549static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1550{
1551 struct hci_cp_sniff_mode *cp;
1552 struct hci_conn *conn;
1553
1554 BT_DBG("%s status 0x%x", hdev->name, status);
1555
1556 if (!status)
1557 return;
1558
1559 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1560 if (!cp)
1561 return;
1562
1563 hci_dev_lock(hdev);
1564
1565 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001566 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001567 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001568
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001569 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001570 hci_sco_setup(conn, status);
1571 }
1572
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001573 hci_dev_unlock(hdev);
1574}
1575
1576static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1577{
1578 struct hci_cp_exit_sniff_mode *cp;
1579 struct hci_conn *conn;
1580
1581 BT_DBG("%s status 0x%x", hdev->name, status);
1582
1583 if (!status)
1584 return;
1585
1586 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1587 if (!cp)
1588 return;
1589
1590 hci_dev_lock(hdev);
1591
1592 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001593 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001594 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001595
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001596 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001597 hci_sco_setup(conn, status);
1598 }
1599
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001600 hci_dev_unlock(hdev);
1601}
1602
Johan Hedberg88c3df12012-02-09 14:27:38 +02001603static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1604{
1605 struct hci_cp_disconnect *cp;
1606 struct hci_conn *conn;
1607
1608 if (!status)
1609 return;
1610
1611 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1612 if (!cp)
1613 return;
1614
1615 hci_dev_lock(hdev);
1616
1617 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1618 if (conn)
1619 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001620 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001621
1622 hci_dev_unlock(hdev);
1623}
1624
Ville Tervofcd89c02011-02-10 22:38:47 -03001625static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1626{
1627 struct hci_cp_le_create_conn *cp;
1628 struct hci_conn *conn;
1629
1630 BT_DBG("%s status 0x%x", hdev->name, status);
1631
1632 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1633 if (!cp)
1634 return;
1635
1636 hci_dev_lock(hdev);
1637
1638 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1639
1640 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001641 conn);
Ville Tervofcd89c02011-02-10 22:38:47 -03001642
1643 if (status) {
1644 if (conn && conn->state == BT_CONNECT) {
1645 conn->state = BT_CLOSED;
Hemant Gupta328c9242012-04-05 16:51:04 +05301646 mgmt_connect_failed(hdev, &cp->peer_addr, conn->type,
1647 conn->dst_type, status);
Ville Tervofcd89c02011-02-10 22:38:47 -03001648 hci_proto_connect_cfm(conn, status);
1649 hci_conn_del(conn);
1650 }
1651 } else {
1652 if (!conn) {
1653 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001654 if (conn) {
1655 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001656 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001657 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001658 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001659 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001660 }
1661 }
1662
1663 hci_dev_unlock(hdev);
1664}
1665
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001666static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1667{
1668 BT_DBG("%s status 0x%x", hdev->name, status);
1669}
1670
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001671static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001672{
1673 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001674 struct discovery_state *discov = &hdev->discovery;
1675 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001676
1677 BT_DBG("%s status %d", hdev->name, status);
1678
Johan Hedberg23bb5762010-12-21 23:01:27 +02001679 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001680
1681 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001682
1683 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1684 return;
1685
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001686 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001687 return;
1688
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001689 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001690
Andre Guedes343f9352012-02-17 20:39:37 -03001691 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001692 goto unlock;
1693
1694 if (list_empty(&discov->resolve)) {
1695 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1696 goto unlock;
1697 }
1698
1699 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1700 if (e && hci_resolve_name(hdev, e) == 0) {
1701 e->name_state = NAME_PENDING;
1702 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1703 } else {
1704 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1705 }
1706
1707unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001708 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001709}
1710
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001711static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001713 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001714 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 int num_rsp = *((__u8 *) skb->data);
1716
1717 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1718
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001719 if (!num_rsp)
1720 return;
1721
Andre Guedes1519cc12012-03-21 00:03:38 -03001722 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1723 return;
1724
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001726
Johan Hedberge17acd42011-03-30 23:57:16 +03001727 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001728 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001729
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 bacpy(&data.bdaddr, &info->bdaddr);
1731 data.pscan_rep_mode = info->pscan_rep_mode;
1732 data.pscan_period_mode = info->pscan_period_mode;
1733 data.pscan_mode = info->pscan_mode;
1734 memcpy(data.dev_class, info->dev_class, 3);
1735 data.clock_offset = info->clock_offset;
1736 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001737 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001738
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001739 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001740 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001741 info->dev_class, 0, !name_known, ssp, NULL,
1742 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001744
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 hci_dev_unlock(hdev);
1746}
1747
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001748static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001750 struct hci_ev_conn_complete *ev = (void *) skb->data;
1751 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001753 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001754
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001756
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001757 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001758 if (!conn) {
1759 if (ev->link_type != SCO_LINK)
1760 goto unlock;
1761
1762 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1763 if (!conn)
1764 goto unlock;
1765
1766 conn->type = SCO_LINK;
1767 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001768
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001769 if (!ev->status) {
1770 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001771
1772 if (conn->type == ACL_LINK) {
1773 conn->state = BT_CONFIG;
1774 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001775 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001776 } else
1777 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001778
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001779 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001780 hci_conn_add_sysfs(conn);
1781
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001782 if (test_bit(HCI_AUTH, &hdev->flags))
1783 conn->link_mode |= HCI_LM_AUTH;
1784
1785 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1786 conn->link_mode |= HCI_LM_ENCRYPT;
1787
1788 /* Get remote features */
1789 if (conn->type == ACL_LINK) {
1790 struct hci_cp_read_remote_features cp;
1791 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001792 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001793 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001794 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001795
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001796 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001797 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001798 struct hci_cp_change_conn_ptype cp;
1799 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001800 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001801 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1802 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001803 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001804 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001805 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001806 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001807 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001808 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001809 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001810
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001811 if (conn->type == ACL_LINK)
1812 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001813
Marcel Holtmann769be972008-07-14 20:13:49 +02001814 if (ev->status) {
1815 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001816 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001817 } else if (ev->link_type != ACL_LINK)
1818 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001819
1820unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001822
1823 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824}
1825
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001826static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001828 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 int mask = hdev->link_mode;
1830
Gustavo Padovan807deac2012-05-17 00:36:24 -03001831 BT_DBG("%s bdaddr %s type 0x%x", hdev->name, batostr(&ev->bdaddr),
1832 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833
1834 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1835
Szymon Janc138d22e2011-02-17 16:44:23 +01001836 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001837 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001839 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841
1842 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001843
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001844 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1845 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001846 memcpy(ie->data.dev_class, ev->dev_class, 3);
1847
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1849 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001850 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1851 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001852 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 hci_dev_unlock(hdev);
1854 return;
1855 }
1856 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001857
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 memcpy(conn->dev_class, ev->dev_class, 3);
1859 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001860
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861 hci_dev_unlock(hdev);
1862
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001863 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1864 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001866 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001868 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1869 cp.role = 0x00; /* Become master */
1870 else
1871 cp.role = 0x01; /* Remain slave */
1872
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001873 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1874 &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001875 } else {
1876 struct hci_cp_accept_sync_conn_req cp;
1877
1878 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001879 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001880
1881 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1882 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1883 cp.max_latency = cpu_to_le16(0xffff);
1884 cp.content_format = cpu_to_le16(hdev->voice_setting);
1885 cp.retrans_effort = 0xff;
1886
1887 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001888 sizeof(cp), &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001889 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 } else {
1891 /* Connection rejected */
1892 struct hci_cp_reject_conn_req cp;
1893
1894 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001895 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001896 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 }
1898}
1899
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001900static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001902 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001903 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904
1905 BT_DBG("%s status %d", hdev->name, ev->status);
1906
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 hci_dev_lock(hdev);
1908
Marcel Holtmann04837f62006-07-03 10:02:33 +02001909 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001910 if (!conn)
1911 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001912
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001913 if (ev->status == 0)
1914 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915
Johan Hedbergb644ba32012-01-17 21:48:47 +02001916 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001917 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001918 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001919 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001920 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001921 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001922 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001923 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001924 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001925
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001926 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301927 if (conn->type == ACL_LINK && conn->flush_key)
1928 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001929 hci_proto_disconn_cfm(conn, ev->reason);
1930 hci_conn_del(conn);
1931 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001932
1933unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934 hci_dev_unlock(hdev);
1935}
1936
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001937static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001938{
1939 struct hci_ev_auth_complete *ev = (void *) skb->data;
1940 struct hci_conn *conn;
1941
1942 BT_DBG("%s status %d", hdev->name, ev->status);
1943
1944 hci_dev_lock(hdev);
1945
1946 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001947 if (!conn)
1948 goto unlock;
1949
1950 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001951 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001952 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001953 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001954 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001955 conn->link_mode |= HCI_LM_AUTH;
1956 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001957 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001958 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001959 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001960 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001961 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001962
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001963 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1964 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001965
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001966 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001967 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001968 struct hci_cp_set_conn_encrypt cp;
1969 cp.handle = ev->handle;
1970 cp.encrypt = 0x01;
1971 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001972 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001973 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001974 conn->state = BT_CONNECTED;
1975 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001976 hci_conn_put(conn);
1977 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001978 } else {
1979 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001980
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001981 hci_conn_hold(conn);
1982 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1983 hci_conn_put(conn);
1984 }
1985
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001986 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001987 if (!ev->status) {
1988 struct hci_cp_set_conn_encrypt cp;
1989 cp.handle = ev->handle;
1990 cp.encrypt = 0x01;
1991 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001992 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001993 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001994 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001995 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001996 }
1997 }
1998
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001999unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002000 hci_dev_unlock(hdev);
2001}
2002
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002003static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002004{
Johan Hedberg127178d2010-11-18 22:22:29 +02002005 struct hci_ev_remote_name *ev = (void *) skb->data;
2006 struct hci_conn *conn;
2007
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002008 BT_DBG("%s", hdev->name);
2009
2010 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002011
2012 hci_dev_lock(hdev);
2013
2014 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002015
2016 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2017 goto check_auth;
2018
2019 if (ev->status == 0)
2020 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002021 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002022 else
2023 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2024
2025check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002026 if (!conn)
2027 goto unlock;
2028
2029 if (!hci_outgoing_auth_needed(hdev, conn))
2030 goto unlock;
2031
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002032 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002033 struct hci_cp_auth_requested cp;
2034 cp.handle = __cpu_to_le16(conn->handle);
2035 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2036 }
2037
Johan Hedberg79c6c702011-04-28 11:28:55 -07002038unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002039 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002040}
2041
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002042static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002043{
2044 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2045 struct hci_conn *conn;
2046
2047 BT_DBG("%s status %d", hdev->name, ev->status);
2048
2049 hci_dev_lock(hdev);
2050
2051 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2052 if (conn) {
2053 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002054 if (ev->encrypt) {
2055 /* Encryption implies authentication */
2056 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002057 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002058 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002059 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002060 conn->link_mode &= ~HCI_LM_ENCRYPT;
2061 }
2062
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002063 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002064
Gustavo Padovana7d77232012-05-13 03:20:07 -03002065 if (ev->status && conn->state == BT_CONNECTED) {
Gustavo Padovand839c812012-05-16 12:17:12 -03002066 hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE);
Gustavo Padovana7d77232012-05-13 03:20:07 -03002067 hci_conn_put(conn);
2068 goto unlock;
2069 }
2070
Marcel Holtmannf8558552008-07-14 20:13:49 +02002071 if (conn->state == BT_CONFIG) {
2072 if (!ev->status)
2073 conn->state = BT_CONNECTED;
2074
2075 hci_proto_connect_cfm(conn, ev->status);
2076 hci_conn_put(conn);
2077 } else
2078 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002079 }
2080
Gustavo Padovana7d77232012-05-13 03:20:07 -03002081unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002082 hci_dev_unlock(hdev);
2083}
2084
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002085static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2086 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002087{
2088 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2089 struct hci_conn *conn;
2090
2091 BT_DBG("%s status %d", hdev->name, ev->status);
2092
2093 hci_dev_lock(hdev);
2094
2095 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2096 if (conn) {
2097 if (!ev->status)
2098 conn->link_mode |= HCI_LM_SECURE;
2099
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002100 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002101
2102 hci_key_change_cfm(conn, ev->status);
2103 }
2104
2105 hci_dev_unlock(hdev);
2106}
2107
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002108static void hci_remote_features_evt(struct hci_dev *hdev,
2109 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002110{
2111 struct hci_ev_remote_features *ev = (void *) skb->data;
2112 struct hci_conn *conn;
2113
2114 BT_DBG("%s status %d", hdev->name, ev->status);
2115
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002116 hci_dev_lock(hdev);
2117
2118 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002119 if (!conn)
2120 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002121
Johan Hedbergccd556f2010-11-10 17:11:51 +02002122 if (!ev->status)
2123 memcpy(conn->features, ev->features, 8);
2124
2125 if (conn->state != BT_CONFIG)
2126 goto unlock;
2127
2128 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2129 struct hci_cp_read_remote_ext_features cp;
2130 cp.handle = ev->handle;
2131 cp.page = 0x01;
2132 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002133 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002134 goto unlock;
2135 }
2136
Johan Hedberg671267b2012-05-12 16:11:50 -03002137 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002138 struct hci_cp_remote_name_req cp;
2139 memset(&cp, 0, sizeof(cp));
2140 bacpy(&cp.bdaddr, &conn->dst);
2141 cp.pscan_rep_mode = 0x02;
2142 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002143 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2144 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002145 conn->dst_type, 0, NULL, 0,
2146 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002147
Johan Hedberg127178d2010-11-18 22:22:29 +02002148 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002149 conn->state = BT_CONNECTED;
2150 hci_proto_connect_cfm(conn, ev->status);
2151 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002152 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002153
Johan Hedbergccd556f2010-11-10 17:11:51 +02002154unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002155 hci_dev_unlock(hdev);
2156}
2157
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002158static void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002159{
2160 BT_DBG("%s", hdev->name);
2161}
2162
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002163static void hci_qos_setup_complete_evt(struct hci_dev *hdev,
2164 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002165{
2166 BT_DBG("%s", hdev->name);
2167}
2168
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002169static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002170{
2171 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2172 __u16 opcode;
2173
2174 skb_pull(skb, sizeof(*ev));
2175
2176 opcode = __le16_to_cpu(ev->opcode);
2177
2178 switch (opcode) {
2179 case HCI_OP_INQUIRY_CANCEL:
2180 hci_cc_inquiry_cancel(hdev, skb);
2181 break;
2182
Andre Guedes4d934832012-03-21 00:03:35 -03002183 case HCI_OP_PERIODIC_INQ:
2184 hci_cc_periodic_inq(hdev, skb);
2185 break;
2186
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002187 case HCI_OP_EXIT_PERIODIC_INQ:
2188 hci_cc_exit_periodic_inq(hdev, skb);
2189 break;
2190
2191 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2192 hci_cc_remote_name_req_cancel(hdev, skb);
2193 break;
2194
2195 case HCI_OP_ROLE_DISCOVERY:
2196 hci_cc_role_discovery(hdev, skb);
2197 break;
2198
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002199 case HCI_OP_READ_LINK_POLICY:
2200 hci_cc_read_link_policy(hdev, skb);
2201 break;
2202
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002203 case HCI_OP_WRITE_LINK_POLICY:
2204 hci_cc_write_link_policy(hdev, skb);
2205 break;
2206
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002207 case HCI_OP_READ_DEF_LINK_POLICY:
2208 hci_cc_read_def_link_policy(hdev, skb);
2209 break;
2210
2211 case HCI_OP_WRITE_DEF_LINK_POLICY:
2212 hci_cc_write_def_link_policy(hdev, skb);
2213 break;
2214
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002215 case HCI_OP_RESET:
2216 hci_cc_reset(hdev, skb);
2217 break;
2218
2219 case HCI_OP_WRITE_LOCAL_NAME:
2220 hci_cc_write_local_name(hdev, skb);
2221 break;
2222
2223 case HCI_OP_READ_LOCAL_NAME:
2224 hci_cc_read_local_name(hdev, skb);
2225 break;
2226
2227 case HCI_OP_WRITE_AUTH_ENABLE:
2228 hci_cc_write_auth_enable(hdev, skb);
2229 break;
2230
2231 case HCI_OP_WRITE_ENCRYPT_MODE:
2232 hci_cc_write_encrypt_mode(hdev, skb);
2233 break;
2234
2235 case HCI_OP_WRITE_SCAN_ENABLE:
2236 hci_cc_write_scan_enable(hdev, skb);
2237 break;
2238
2239 case HCI_OP_READ_CLASS_OF_DEV:
2240 hci_cc_read_class_of_dev(hdev, skb);
2241 break;
2242
2243 case HCI_OP_WRITE_CLASS_OF_DEV:
2244 hci_cc_write_class_of_dev(hdev, skb);
2245 break;
2246
2247 case HCI_OP_READ_VOICE_SETTING:
2248 hci_cc_read_voice_setting(hdev, skb);
2249 break;
2250
2251 case HCI_OP_WRITE_VOICE_SETTING:
2252 hci_cc_write_voice_setting(hdev, skb);
2253 break;
2254
2255 case HCI_OP_HOST_BUFFER_SIZE:
2256 hci_cc_host_buffer_size(hdev, skb);
2257 break;
2258
Marcel Holtmann333140b2008-07-14 20:13:48 +02002259 case HCI_OP_WRITE_SSP_MODE:
2260 hci_cc_write_ssp_mode(hdev, skb);
2261 break;
2262
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002263 case HCI_OP_READ_LOCAL_VERSION:
2264 hci_cc_read_local_version(hdev, skb);
2265 break;
2266
2267 case HCI_OP_READ_LOCAL_COMMANDS:
2268 hci_cc_read_local_commands(hdev, skb);
2269 break;
2270
2271 case HCI_OP_READ_LOCAL_FEATURES:
2272 hci_cc_read_local_features(hdev, skb);
2273 break;
2274
Andre Guedes971e3a42011-06-30 19:20:52 -03002275 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2276 hci_cc_read_local_ext_features(hdev, skb);
2277 break;
2278
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002279 case HCI_OP_READ_BUFFER_SIZE:
2280 hci_cc_read_buffer_size(hdev, skb);
2281 break;
2282
2283 case HCI_OP_READ_BD_ADDR:
2284 hci_cc_read_bd_addr(hdev, skb);
2285 break;
2286
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002287 case HCI_OP_READ_DATA_BLOCK_SIZE:
2288 hci_cc_read_data_block_size(hdev, skb);
2289 break;
2290
Johan Hedberg23bb5762010-12-21 23:01:27 +02002291 case HCI_OP_WRITE_CA_TIMEOUT:
2292 hci_cc_write_ca_timeout(hdev, skb);
2293 break;
2294
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002295 case HCI_OP_READ_FLOW_CONTROL_MODE:
2296 hci_cc_read_flow_control_mode(hdev, skb);
2297 break;
2298
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002299 case HCI_OP_READ_LOCAL_AMP_INFO:
2300 hci_cc_read_local_amp_info(hdev, skb);
2301 break;
2302
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002303 case HCI_OP_DELETE_STORED_LINK_KEY:
2304 hci_cc_delete_stored_link_key(hdev, skb);
2305 break;
2306
Johan Hedbergd5859e22011-01-25 01:19:58 +02002307 case HCI_OP_SET_EVENT_MASK:
2308 hci_cc_set_event_mask(hdev, skb);
2309 break;
2310
2311 case HCI_OP_WRITE_INQUIRY_MODE:
2312 hci_cc_write_inquiry_mode(hdev, skb);
2313 break;
2314
2315 case HCI_OP_READ_INQ_RSP_TX_POWER:
2316 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2317 break;
2318
2319 case HCI_OP_SET_EVENT_FLT:
2320 hci_cc_set_event_flt(hdev, skb);
2321 break;
2322
Johan Hedberg980e1a52011-01-22 06:10:07 +02002323 case HCI_OP_PIN_CODE_REPLY:
2324 hci_cc_pin_code_reply(hdev, skb);
2325 break;
2326
2327 case HCI_OP_PIN_CODE_NEG_REPLY:
2328 hci_cc_pin_code_neg_reply(hdev, skb);
2329 break;
2330
Szymon Jancc35938b2011-03-22 13:12:21 +01002331 case HCI_OP_READ_LOCAL_OOB_DATA:
2332 hci_cc_read_local_oob_data_reply(hdev, skb);
2333 break;
2334
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002335 case HCI_OP_LE_READ_BUFFER_SIZE:
2336 hci_cc_le_read_buffer_size(hdev, skb);
2337 break;
2338
Johan Hedberga5c29682011-02-19 12:05:57 -03002339 case HCI_OP_USER_CONFIRM_REPLY:
2340 hci_cc_user_confirm_reply(hdev, skb);
2341 break;
2342
2343 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2344 hci_cc_user_confirm_neg_reply(hdev, skb);
2345 break;
2346
Brian Gix1143d452011-11-23 08:28:34 -08002347 case HCI_OP_USER_PASSKEY_REPLY:
2348 hci_cc_user_passkey_reply(hdev, skb);
2349 break;
2350
2351 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2352 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002353 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002354
2355 case HCI_OP_LE_SET_SCAN_PARAM:
2356 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002357 break;
2358
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002359 case HCI_OP_LE_SET_SCAN_ENABLE:
2360 hci_cc_le_set_scan_enable(hdev, skb);
2361 break;
2362
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002363 case HCI_OP_LE_LTK_REPLY:
2364 hci_cc_le_ltk_reply(hdev, skb);
2365 break;
2366
2367 case HCI_OP_LE_LTK_NEG_REPLY:
2368 hci_cc_le_ltk_neg_reply(hdev, skb);
2369 break;
2370
Andre Guedesf9b49302011-06-30 19:20:53 -03002371 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2372 hci_cc_write_le_host_supported(hdev, skb);
2373 break;
2374
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002375 default:
2376 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2377 break;
2378 }
2379
Ville Tervo6bd32322011-02-16 16:32:41 +02002380 if (ev->opcode != HCI_OP_NOP)
2381 del_timer(&hdev->cmd_timer);
2382
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002383 if (ev->ncmd) {
2384 atomic_set(&hdev->cmd_cnt, 1);
2385 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002386 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002387 }
2388}
2389
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002390static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002391{
2392 struct hci_ev_cmd_status *ev = (void *) skb->data;
2393 __u16 opcode;
2394
2395 skb_pull(skb, sizeof(*ev));
2396
2397 opcode = __le16_to_cpu(ev->opcode);
2398
2399 switch (opcode) {
2400 case HCI_OP_INQUIRY:
2401 hci_cs_inquiry(hdev, ev->status);
2402 break;
2403
2404 case HCI_OP_CREATE_CONN:
2405 hci_cs_create_conn(hdev, ev->status);
2406 break;
2407
2408 case HCI_OP_ADD_SCO:
2409 hci_cs_add_sco(hdev, ev->status);
2410 break;
2411
Marcel Holtmannf8558552008-07-14 20:13:49 +02002412 case HCI_OP_AUTH_REQUESTED:
2413 hci_cs_auth_requested(hdev, ev->status);
2414 break;
2415
2416 case HCI_OP_SET_CONN_ENCRYPT:
2417 hci_cs_set_conn_encrypt(hdev, ev->status);
2418 break;
2419
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002420 case HCI_OP_REMOTE_NAME_REQ:
2421 hci_cs_remote_name_req(hdev, ev->status);
2422 break;
2423
Marcel Holtmann769be972008-07-14 20:13:49 +02002424 case HCI_OP_READ_REMOTE_FEATURES:
2425 hci_cs_read_remote_features(hdev, ev->status);
2426 break;
2427
2428 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2429 hci_cs_read_remote_ext_features(hdev, ev->status);
2430 break;
2431
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002432 case HCI_OP_SETUP_SYNC_CONN:
2433 hci_cs_setup_sync_conn(hdev, ev->status);
2434 break;
2435
2436 case HCI_OP_SNIFF_MODE:
2437 hci_cs_sniff_mode(hdev, ev->status);
2438 break;
2439
2440 case HCI_OP_EXIT_SNIFF_MODE:
2441 hci_cs_exit_sniff_mode(hdev, ev->status);
2442 break;
2443
Johan Hedberg8962ee72011-01-20 12:40:27 +02002444 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002445 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002446 break;
2447
Ville Tervofcd89c02011-02-10 22:38:47 -03002448 case HCI_OP_LE_CREATE_CONN:
2449 hci_cs_le_create_conn(hdev, ev->status);
2450 break;
2451
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002452 case HCI_OP_LE_START_ENC:
2453 hci_cs_le_start_enc(hdev, ev->status);
2454 break;
2455
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002456 default:
2457 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2458 break;
2459 }
2460
Ville Tervo6bd32322011-02-16 16:32:41 +02002461 if (ev->opcode != HCI_OP_NOP)
2462 del_timer(&hdev->cmd_timer);
2463
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002464 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002465 atomic_set(&hdev->cmd_cnt, 1);
2466 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002467 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002468 }
2469}
2470
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002471static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002472{
2473 struct hci_ev_role_change *ev = (void *) skb->data;
2474 struct hci_conn *conn;
2475
2476 BT_DBG("%s status %d", hdev->name, ev->status);
2477
2478 hci_dev_lock(hdev);
2479
2480 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2481 if (conn) {
2482 if (!ev->status) {
2483 if (ev->role)
2484 conn->link_mode &= ~HCI_LM_MASTER;
2485 else
2486 conn->link_mode |= HCI_LM_MASTER;
2487 }
2488
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002489 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002490
2491 hci_role_switch_cfm(conn, ev->status, ev->role);
2492 }
2493
2494 hci_dev_unlock(hdev);
2495}
2496
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002497static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002499 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500 int i;
2501
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002502 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2503 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2504 return;
2505 }
2506
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002507 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002508 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509 BT_DBG("%s bad parameters", hdev->name);
2510 return;
2511 }
2512
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002513 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2514
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002515 for (i = 0; i < ev->num_hndl; i++) {
2516 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002517 struct hci_conn *conn;
2518 __u16 handle, count;
2519
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002520 handle = __le16_to_cpu(info->handle);
2521 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522
2523 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002524 if (!conn)
2525 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002527 conn->sent -= count;
2528
2529 switch (conn->type) {
2530 case ACL_LINK:
2531 hdev->acl_cnt += count;
2532 if (hdev->acl_cnt > hdev->acl_pkts)
2533 hdev->acl_cnt = hdev->acl_pkts;
2534 break;
2535
2536 case LE_LINK:
2537 if (hdev->le_pkts) {
2538 hdev->le_cnt += count;
2539 if (hdev->le_cnt > hdev->le_pkts)
2540 hdev->le_cnt = hdev->le_pkts;
2541 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002542 hdev->acl_cnt += count;
2543 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544 hdev->acl_cnt = hdev->acl_pkts;
2545 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002546 break;
2547
2548 case SCO_LINK:
2549 hdev->sco_cnt += count;
2550 if (hdev->sco_cnt > hdev->sco_pkts)
2551 hdev->sco_cnt = hdev->sco_pkts;
2552 break;
2553
2554 default:
2555 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2556 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557 }
2558 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002559
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002560 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561}
2562
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002563static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002564{
2565 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2566 int i;
2567
2568 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2569 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2570 return;
2571 }
2572
2573 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002574 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002575 BT_DBG("%s bad parameters", hdev->name);
2576 return;
2577 }
2578
2579 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002580 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002581
2582 for (i = 0; i < ev->num_hndl; i++) {
2583 struct hci_comp_blocks_info *info = &ev->handles[i];
2584 struct hci_conn *conn;
2585 __u16 handle, block_count;
2586
2587 handle = __le16_to_cpu(info->handle);
2588 block_count = __le16_to_cpu(info->blocks);
2589
2590 conn = hci_conn_hash_lookup_handle(hdev, handle);
2591 if (!conn)
2592 continue;
2593
2594 conn->sent -= block_count;
2595
2596 switch (conn->type) {
2597 case ACL_LINK:
2598 hdev->block_cnt += block_count;
2599 if (hdev->block_cnt > hdev->num_blocks)
2600 hdev->block_cnt = hdev->num_blocks;
2601 break;
2602
2603 default:
2604 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2605 break;
2606 }
2607 }
2608
2609 queue_work(hdev->workqueue, &hdev->tx_work);
2610}
2611
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002612static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002613{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002614 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002615 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002616
2617 BT_DBG("%s status %d", hdev->name, ev->status);
2618
2619 hci_dev_lock(hdev);
2620
Marcel Holtmann04837f62006-07-03 10:02:33 +02002621 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2622 if (conn) {
2623 conn->mode = ev->mode;
2624 conn->interval = __le16_to_cpu(ev->interval);
2625
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002626 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002627 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002628 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002629 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002630 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002631 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002632
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002633 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002634 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002635 }
2636
2637 hci_dev_unlock(hdev);
2638}
2639
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002640static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002642 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2643 struct hci_conn *conn;
2644
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002645 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002646
2647 hci_dev_lock(hdev);
2648
2649 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002650 if (!conn)
2651 goto unlock;
2652
2653 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002654 hci_conn_hold(conn);
2655 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2656 hci_conn_put(conn);
2657 }
2658
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002659 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002660 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002661 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002662 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002663 u8 secure;
2664
2665 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2666 secure = 1;
2667 else
2668 secure = 0;
2669
Johan Hedberg744cf192011-11-08 20:40:14 +02002670 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002671 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002672
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002673unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002674 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002675}
2676
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002677static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002679 struct hci_ev_link_key_req *ev = (void *) skb->data;
2680 struct hci_cp_link_key_reply cp;
2681 struct hci_conn *conn;
2682 struct link_key *key;
2683
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002684 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002685
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002686 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002687 return;
2688
2689 hci_dev_lock(hdev);
2690
2691 key = hci_find_link_key(hdev, &ev->bdaddr);
2692 if (!key) {
2693 BT_DBG("%s link key not found for %s", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002694 batostr(&ev->bdaddr));
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002695 goto not_found;
2696 }
2697
2698 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002699 batostr(&ev->bdaddr));
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002700
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002701 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002702 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002703 BT_DBG("%s ignoring debug key", hdev->name);
2704 goto not_found;
2705 }
2706
2707 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002708 if (conn) {
2709 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002710 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002711 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2712 goto not_found;
2713 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002714
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002715 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002716 conn->pending_sec_level == BT_SECURITY_HIGH) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002717 BT_DBG("%s ignoring key unauthenticated for high \
Gustavo Padovan807deac2012-05-17 00:36:24 -03002718 security", hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002719 goto not_found;
2720 }
2721
2722 conn->key_type = key->type;
2723 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002724 }
2725
2726 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002727 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002728
2729 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2730
2731 hci_dev_unlock(hdev);
2732
2733 return;
2734
2735not_found:
2736 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2737 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738}
2739
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002740static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002742 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2743 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002744 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002745
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002746 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002747
2748 hci_dev_lock(hdev);
2749
2750 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2751 if (conn) {
2752 hci_conn_hold(conn);
2753 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002754 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002755
2756 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2757 conn->key_type = ev->key_type;
2758
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002759 hci_conn_put(conn);
2760 }
2761
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002762 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002763 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002764 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002765
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002766 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767}
2768
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002769static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002770{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002771 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002772 struct hci_conn *conn;
2773
2774 BT_DBG("%s status %d", hdev->name, ev->status);
2775
2776 hci_dev_lock(hdev);
2777
2778 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002779 if (conn && !ev->status) {
2780 struct inquiry_entry *ie;
2781
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002782 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2783 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002784 ie->data.clock_offset = ev->clock_offset;
2785 ie->timestamp = jiffies;
2786 }
2787 }
2788
2789 hci_dev_unlock(hdev);
2790}
2791
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002792static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002793{
2794 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2795 struct hci_conn *conn;
2796
2797 BT_DBG("%s status %d", hdev->name, ev->status);
2798
2799 hci_dev_lock(hdev);
2800
2801 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2802 if (conn && !ev->status)
2803 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2804
2805 hci_dev_unlock(hdev);
2806}
2807
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002808static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002809{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002810 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002811 struct inquiry_entry *ie;
2812
2813 BT_DBG("%s", hdev->name);
2814
2815 hci_dev_lock(hdev);
2816
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002817 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2818 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002819 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2820 ie->timestamp = jiffies;
2821 }
2822
2823 hci_dev_unlock(hdev);
2824}
2825
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002826static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2827 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002828{
2829 struct inquiry_data data;
2830 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002831 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002832
2833 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2834
2835 if (!num_rsp)
2836 return;
2837
Andre Guedes1519cc12012-03-21 00:03:38 -03002838 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2839 return;
2840
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002841 hci_dev_lock(hdev);
2842
2843 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002844 struct inquiry_info_with_rssi_and_pscan_mode *info;
2845 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002846
Johan Hedberge17acd42011-03-30 23:57:16 +03002847 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002848 bacpy(&data.bdaddr, &info->bdaddr);
2849 data.pscan_rep_mode = info->pscan_rep_mode;
2850 data.pscan_period_mode = info->pscan_period_mode;
2851 data.pscan_mode = info->pscan_mode;
2852 memcpy(data.dev_class, info->dev_class, 3);
2853 data.clock_offset = info->clock_offset;
2854 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002855 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002856
2857 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002858 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002859 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002860 info->dev_class, info->rssi,
2861 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002862 }
2863 } else {
2864 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2865
Johan Hedberge17acd42011-03-30 23:57:16 +03002866 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002867 bacpy(&data.bdaddr, &info->bdaddr);
2868 data.pscan_rep_mode = info->pscan_rep_mode;
2869 data.pscan_period_mode = info->pscan_period_mode;
2870 data.pscan_mode = 0x00;
2871 memcpy(data.dev_class, info->dev_class, 3);
2872 data.clock_offset = info->clock_offset;
2873 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002874 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002875 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002876 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002877 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002878 info->dev_class, info->rssi,
2879 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002880 }
2881 }
2882
2883 hci_dev_unlock(hdev);
2884}
2885
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002886static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2887 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002888{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002889 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2890 struct hci_conn *conn;
2891
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002892 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002893
Marcel Holtmann41a96212008-07-14 20:13:48 +02002894 hci_dev_lock(hdev);
2895
2896 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002897 if (!conn)
2898 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002899
Johan Hedbergccd556f2010-11-10 17:11:51 +02002900 if (!ev->status && ev->page == 0x01) {
2901 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002902
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002903 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2904 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002905 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002906
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002907 if (ev->features[0] & LMP_HOST_SSP)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002908 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002909 }
2910
Johan Hedbergccd556f2010-11-10 17:11:51 +02002911 if (conn->state != BT_CONFIG)
2912 goto unlock;
2913
Johan Hedberg671267b2012-05-12 16:11:50 -03002914 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002915 struct hci_cp_remote_name_req cp;
2916 memset(&cp, 0, sizeof(cp));
2917 bacpy(&cp.bdaddr, &conn->dst);
2918 cp.pscan_rep_mode = 0x02;
2919 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002920 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2921 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002922 conn->dst_type, 0, NULL, 0,
2923 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002924
Johan Hedberg127178d2010-11-18 22:22:29 +02002925 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002926 conn->state = BT_CONNECTED;
2927 hci_proto_connect_cfm(conn, ev->status);
2928 hci_conn_put(conn);
2929 }
2930
2931unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002932 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002933}
2934
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002935static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2936 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002937{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002938 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2939 struct hci_conn *conn;
2940
2941 BT_DBG("%s status %d", hdev->name, ev->status);
2942
2943 hci_dev_lock(hdev);
2944
2945 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002946 if (!conn) {
2947 if (ev->link_type == ESCO_LINK)
2948 goto unlock;
2949
2950 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2951 if (!conn)
2952 goto unlock;
2953
2954 conn->type = SCO_LINK;
2955 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002956
Marcel Holtmann732547f2009-04-19 19:14:14 +02002957 switch (ev->status) {
2958 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002959 conn->handle = __le16_to_cpu(ev->handle);
2960 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002961
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002962 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002963 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002964 break;
2965
Stephen Coe705e5712010-02-16 11:29:44 -05002966 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002967 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002968 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002969 case 0x1f: /* Unspecified error */
2970 if (conn->out && conn->attempt < 2) {
2971 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2972 (hdev->esco_type & EDR_ESCO_MASK);
2973 hci_setup_sync(conn, conn->link->handle);
2974 goto unlock;
2975 }
2976 /* fall through */
2977
2978 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002979 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002980 break;
2981 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002982
2983 hci_proto_connect_cfm(conn, ev->status);
2984 if (ev->status)
2985 hci_conn_del(conn);
2986
2987unlock:
2988 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002989}
2990
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002991static void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002992{
2993 BT_DBG("%s", hdev->name);
2994}
2995
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002996static void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002997{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002998 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002999
3000 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02003001}
3002
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003003static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3004 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003005{
3006 struct inquiry_data data;
3007 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3008 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303009 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003010
3011 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3012
3013 if (!num_rsp)
3014 return;
3015
Andre Guedes1519cc12012-03-21 00:03:38 -03003016 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3017 return;
3018
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003019 hci_dev_lock(hdev);
3020
Johan Hedberge17acd42011-03-30 23:57:16 +03003021 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003022 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003023
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003024 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003025 data.pscan_rep_mode = info->pscan_rep_mode;
3026 data.pscan_period_mode = info->pscan_period_mode;
3027 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003028 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003029 data.clock_offset = info->clock_offset;
3030 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003031 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003032
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003033 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003034 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003035 sizeof(info->data),
3036 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003037 else
3038 name_known = true;
3039
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003040 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003041 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303042 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003043 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003044 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303045 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003046 }
3047
3048 hci_dev_unlock(hdev);
3049}
3050
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003051static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003052{
3053 /* If remote requests dedicated bonding follow that lead */
3054 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3055 /* If both remote and local IO capabilities allow MITM
3056 * protection then require it, otherwise don't */
3057 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3058 return 0x02;
3059 else
3060 return 0x03;
3061 }
3062
3063 /* If remote requests no-bonding follow that lead */
3064 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003065 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003066
3067 return conn->auth_type;
3068}
3069
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003070static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003071{
3072 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3073 struct hci_conn *conn;
3074
3075 BT_DBG("%s", hdev->name);
3076
3077 hci_dev_lock(hdev);
3078
3079 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003080 if (!conn)
3081 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003082
Johan Hedberg03b555e2011-01-04 15:40:05 +02003083 hci_conn_hold(conn);
3084
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003085 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003086 goto unlock;
3087
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003088 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003089 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003090 struct hci_cp_io_capability_reply cp;
3091
3092 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303093 /* Change the IO capability from KeyboardDisplay
3094 * to DisplayYesNo as it is not supported by BT spec. */
3095 cp.capability = (conn->io_capability == 0x04) ?
3096 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003097 conn->auth_type = hci_get_auth_req(conn);
3098 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003099
Johan Hedberg58a681e2012-01-16 06:47:28 +02003100 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003101 hci_find_remote_oob_data(hdev, &conn->dst))
Szymon Jancce85ee12011-03-22 13:12:23 +01003102 cp.oob_data = 0x01;
3103 else
3104 cp.oob_data = 0x00;
3105
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003106 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003107 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003108 } else {
3109 struct hci_cp_io_capability_neg_reply cp;
3110
3111 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003112 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003113
3114 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003115 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003116 }
3117
3118unlock:
3119 hci_dev_unlock(hdev);
3120}
3121
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003122static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003123{
3124 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3125 struct hci_conn *conn;
3126
3127 BT_DBG("%s", hdev->name);
3128
3129 hci_dev_lock(hdev);
3130
3131 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3132 if (!conn)
3133 goto unlock;
3134
Johan Hedberg03b555e2011-01-04 15:40:05 +02003135 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003136 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003137 if (ev->oob_data)
3138 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003139
3140unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003141 hci_dev_unlock(hdev);
3142}
3143
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003144static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3145 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003146{
3147 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003148 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003149 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003150
3151 BT_DBG("%s", hdev->name);
3152
3153 hci_dev_lock(hdev);
3154
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003155 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003156 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003157
Johan Hedberg7a828902011-04-28 11:28:53 -07003158 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3159 if (!conn)
3160 goto unlock;
3161
3162 loc_mitm = (conn->auth_type & 0x01);
3163 rem_mitm = (conn->remote_auth & 0x01);
3164
3165 /* If we require MITM but the remote device can't provide that
3166 * (it has NoInputNoOutput) then reject the confirmation
3167 * request. The only exception is when we're dedicated bonding
3168 * initiators (connect_cfm_cb set) since then we always have the MITM
3169 * bit set. */
3170 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3171 BT_DBG("Rejecting request: remote device can't provide MITM");
3172 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003173 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003174 goto unlock;
3175 }
3176
3177 /* If no side requires MITM protection; auto-accept */
3178 if ((!loc_mitm || conn->remote_cap == 0x03) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003179 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003180
3181 /* If we're not the initiators request authorization to
3182 * proceed from user space (mgmt_user_confirm with
3183 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003184 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003185 BT_DBG("Confirming auto-accept as acceptor");
3186 confirm_hint = 1;
3187 goto confirm;
3188 }
3189
Johan Hedberg9f616562011-04-28 11:28:54 -07003190 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003191 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003192
3193 if (hdev->auto_accept_delay > 0) {
3194 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3195 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3196 goto unlock;
3197 }
3198
Johan Hedberg7a828902011-04-28 11:28:53 -07003199 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003200 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003201 goto unlock;
3202 }
3203
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003204confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003205 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003206 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003207
3208unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003209 hci_dev_unlock(hdev);
3210}
3211
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003212static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3213 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003214{
3215 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3216
3217 BT_DBG("%s", hdev->name);
3218
3219 hci_dev_lock(hdev);
3220
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003221 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003222 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003223
3224 hci_dev_unlock(hdev);
3225}
3226
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003227static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3228 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003229{
3230 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3231 struct hci_conn *conn;
3232
3233 BT_DBG("%s", hdev->name);
3234
3235 hci_dev_lock(hdev);
3236
3237 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003238 if (!conn)
3239 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003240
Johan Hedberg2a611692011-02-19 12:06:00 -03003241 /* To avoid duplicate auth_failed events to user space we check
3242 * the HCI_CONN_AUTH_PEND flag which will be set if we
3243 * initiated the authentication. A traditional auth_complete
3244 * event gets always produced as initiator and is also mapped to
3245 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003246 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003247 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003248 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003249
3250 hci_conn_put(conn);
3251
3252unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003253 hci_dev_unlock(hdev);
3254}
3255
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003256static void hci_remote_host_features_evt(struct hci_dev *hdev,
3257 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003258{
3259 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3260 struct inquiry_entry *ie;
3261
3262 BT_DBG("%s", hdev->name);
3263
3264 hci_dev_lock(hdev);
3265
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003266 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3267 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003268 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003269
3270 hci_dev_unlock(hdev);
3271}
3272
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003273static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3274 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003275{
3276 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3277 struct oob_data *data;
3278
3279 BT_DBG("%s", hdev->name);
3280
3281 hci_dev_lock(hdev);
3282
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003283 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003284 goto unlock;
3285
Szymon Janc2763eda2011-03-22 13:12:22 +01003286 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3287 if (data) {
3288 struct hci_cp_remote_oob_data_reply cp;
3289
3290 bacpy(&cp.bdaddr, &ev->bdaddr);
3291 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3292 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3293
3294 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003295 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003296 } else {
3297 struct hci_cp_remote_oob_data_neg_reply cp;
3298
3299 bacpy(&cp.bdaddr, &ev->bdaddr);
3300 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003301 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003302 }
3303
Szymon Jance1ba1f12011-04-06 13:01:59 +02003304unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003305 hci_dev_unlock(hdev);
3306}
3307
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003308static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003309{
3310 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3311 struct hci_conn *conn;
3312
3313 BT_DBG("%s status %d", hdev->name, ev->status);
3314
3315 hci_dev_lock(hdev);
3316
3317 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003318 if (!conn) {
3319 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3320 if (!conn) {
3321 BT_ERR("No memory for new connection");
3322 hci_dev_unlock(hdev);
3323 return;
3324 }
Andre Guedes29b79882011-05-31 14:20:54 -03003325
3326 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003327 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003328
3329 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003330 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003331 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003332 hci_proto_connect_cfm(conn, ev->status);
3333 conn->state = BT_CLOSED;
3334 hci_conn_del(conn);
3335 goto unlock;
3336 }
3337
Johan Hedbergb644ba32012-01-17 21:48:47 +02003338 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3339 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003340 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003341
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003342 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003343 conn->handle = __le16_to_cpu(ev->handle);
3344 conn->state = BT_CONNECTED;
3345
3346 hci_conn_hold_device(conn);
3347 hci_conn_add_sysfs(conn);
3348
3349 hci_proto_connect_cfm(conn, ev->status);
3350
3351unlock:
3352 hci_dev_unlock(hdev);
3353}
3354
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003355static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003356{
Andre Guedese95beb42011-09-26 20:48:35 -03003357 u8 num_reports = skb->data[0];
3358 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003359 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003360
3361 hci_dev_lock(hdev);
3362
Andre Guedese95beb42011-09-26 20:48:35 -03003363 while (num_reports--) {
3364 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003365
Andre Guedes3c9e9192012-01-10 18:20:50 -03003366 rssi = ev->data[ev->length];
3367 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003368 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003369
Andre Guedese95beb42011-09-26 20:48:35 -03003370 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003371 }
3372
3373 hci_dev_unlock(hdev);
3374}
3375
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003376static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003377{
3378 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3379 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003380 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003381 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003382 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003383
Andrei Emeltchenkoe4666882012-03-09 11:59:15 +02003384 BT_DBG("%s handle %d", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003385
3386 hci_dev_lock(hdev);
3387
3388 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003389 if (conn == NULL)
3390 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003391
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003392 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3393 if (ltk == NULL)
3394 goto not_found;
3395
3396 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003397 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003398
3399 if (ltk->authenticated)
3400 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003401
3402 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3403
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003404 if (ltk->type & HCI_SMP_STK) {
3405 list_del(&ltk->list);
3406 kfree(ltk);
3407 }
3408
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003409 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003410
3411 return;
3412
3413not_found:
3414 neg.handle = ev->handle;
3415 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3416 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003417}
3418
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003419static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003420{
3421 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3422
3423 skb_pull(skb, sizeof(*le_ev));
3424
3425 switch (le_ev->subevent) {
3426 case HCI_EV_LE_CONN_COMPLETE:
3427 hci_le_conn_complete_evt(hdev, skb);
3428 break;
3429
Andre Guedes9aa04c92011-05-26 16:23:51 -03003430 case HCI_EV_LE_ADVERTISING_REPORT:
3431 hci_le_adv_report_evt(hdev, skb);
3432 break;
3433
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003434 case HCI_EV_LE_LTK_REQ:
3435 hci_le_ltk_request_evt(hdev, skb);
3436 break;
3437
Ville Tervofcd89c02011-02-10 22:38:47 -03003438 default:
3439 break;
3440 }
3441}
3442
Linus Torvalds1da177e2005-04-16 15:20:36 -07003443void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3444{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003445 struct hci_event_hdr *hdr = (void *) skb->data;
3446 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003447
3448 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3449
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003450 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003451 case HCI_EV_INQUIRY_COMPLETE:
3452 hci_inquiry_complete_evt(hdev, skb);
3453 break;
3454
3455 case HCI_EV_INQUIRY_RESULT:
3456 hci_inquiry_result_evt(hdev, skb);
3457 break;
3458
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003459 case HCI_EV_CONN_COMPLETE:
3460 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003461 break;
3462
Linus Torvalds1da177e2005-04-16 15:20:36 -07003463 case HCI_EV_CONN_REQUEST:
3464 hci_conn_request_evt(hdev, skb);
3465 break;
3466
Linus Torvalds1da177e2005-04-16 15:20:36 -07003467 case HCI_EV_DISCONN_COMPLETE:
3468 hci_disconn_complete_evt(hdev, skb);
3469 break;
3470
Linus Torvalds1da177e2005-04-16 15:20:36 -07003471 case HCI_EV_AUTH_COMPLETE:
3472 hci_auth_complete_evt(hdev, skb);
3473 break;
3474
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003475 case HCI_EV_REMOTE_NAME:
3476 hci_remote_name_evt(hdev, skb);
3477 break;
3478
Linus Torvalds1da177e2005-04-16 15:20:36 -07003479 case HCI_EV_ENCRYPT_CHANGE:
3480 hci_encrypt_change_evt(hdev, skb);
3481 break;
3482
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003483 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3484 hci_change_link_key_complete_evt(hdev, skb);
3485 break;
3486
3487 case HCI_EV_REMOTE_FEATURES:
3488 hci_remote_features_evt(hdev, skb);
3489 break;
3490
3491 case HCI_EV_REMOTE_VERSION:
3492 hci_remote_version_evt(hdev, skb);
3493 break;
3494
3495 case HCI_EV_QOS_SETUP_COMPLETE:
3496 hci_qos_setup_complete_evt(hdev, skb);
3497 break;
3498
3499 case HCI_EV_CMD_COMPLETE:
3500 hci_cmd_complete_evt(hdev, skb);
3501 break;
3502
3503 case HCI_EV_CMD_STATUS:
3504 hci_cmd_status_evt(hdev, skb);
3505 break;
3506
3507 case HCI_EV_ROLE_CHANGE:
3508 hci_role_change_evt(hdev, skb);
3509 break;
3510
3511 case HCI_EV_NUM_COMP_PKTS:
3512 hci_num_comp_pkts_evt(hdev, skb);
3513 break;
3514
3515 case HCI_EV_MODE_CHANGE:
3516 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003517 break;
3518
3519 case HCI_EV_PIN_CODE_REQ:
3520 hci_pin_code_request_evt(hdev, skb);
3521 break;
3522
3523 case HCI_EV_LINK_KEY_REQ:
3524 hci_link_key_request_evt(hdev, skb);
3525 break;
3526
3527 case HCI_EV_LINK_KEY_NOTIFY:
3528 hci_link_key_notify_evt(hdev, skb);
3529 break;
3530
3531 case HCI_EV_CLOCK_OFFSET:
3532 hci_clock_offset_evt(hdev, skb);
3533 break;
3534
Marcel Holtmanna8746412008-07-14 20:13:46 +02003535 case HCI_EV_PKT_TYPE_CHANGE:
3536 hci_pkt_type_change_evt(hdev, skb);
3537 break;
3538
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003539 case HCI_EV_PSCAN_REP_MODE:
3540 hci_pscan_rep_mode_evt(hdev, skb);
3541 break;
3542
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003543 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3544 hci_inquiry_result_with_rssi_evt(hdev, skb);
3545 break;
3546
3547 case HCI_EV_REMOTE_EXT_FEATURES:
3548 hci_remote_ext_features_evt(hdev, skb);
3549 break;
3550
3551 case HCI_EV_SYNC_CONN_COMPLETE:
3552 hci_sync_conn_complete_evt(hdev, skb);
3553 break;
3554
3555 case HCI_EV_SYNC_CONN_CHANGED:
3556 hci_sync_conn_changed_evt(hdev, skb);
3557 break;
3558
Marcel Holtmann04837f62006-07-03 10:02:33 +02003559 case HCI_EV_SNIFF_SUBRATE:
3560 hci_sniff_subrate_evt(hdev, skb);
3561 break;
3562
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003563 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3564 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003565 break;
3566
Marcel Holtmann04936842008-07-14 20:13:48 +02003567 case HCI_EV_IO_CAPA_REQUEST:
3568 hci_io_capa_request_evt(hdev, skb);
3569 break;
3570
Johan Hedberg03b555e2011-01-04 15:40:05 +02003571 case HCI_EV_IO_CAPA_REPLY:
3572 hci_io_capa_reply_evt(hdev, skb);
3573 break;
3574
Johan Hedberga5c29682011-02-19 12:05:57 -03003575 case HCI_EV_USER_CONFIRM_REQUEST:
3576 hci_user_confirm_request_evt(hdev, skb);
3577 break;
3578
Brian Gix1143d452011-11-23 08:28:34 -08003579 case HCI_EV_USER_PASSKEY_REQUEST:
3580 hci_user_passkey_request_evt(hdev, skb);
3581 break;
3582
Marcel Holtmann04936842008-07-14 20:13:48 +02003583 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3584 hci_simple_pair_complete_evt(hdev, skb);
3585 break;
3586
Marcel Holtmann41a96212008-07-14 20:13:48 +02003587 case HCI_EV_REMOTE_HOST_FEATURES:
3588 hci_remote_host_features_evt(hdev, skb);
3589 break;
3590
Ville Tervofcd89c02011-02-10 22:38:47 -03003591 case HCI_EV_LE_META:
3592 hci_le_meta_evt(hdev, skb);
3593 break;
3594
Szymon Janc2763eda2011-03-22 13:12:22 +01003595 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3596 hci_remote_oob_data_request_evt(hdev, skb);
3597 break;
3598
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003599 case HCI_EV_NUM_COMP_BLOCKS:
3600 hci_num_comp_blocks_evt(hdev, skb);
3601 break;
3602
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003603 default:
3604 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003605 break;
3606 }
3607
3608 kfree_skb(skb);
3609 hdev->stat.evt_rx++;
3610}