blob: f00faf0ac32fa34c8d2285abc6d8897b2988e717 [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
40#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020041#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <asm/unaligned.h>
43
44#include <net/bluetooth/bluetooth.h>
45#include <net/bluetooth/hci_core.h>
46
Rusty Russelleb939922011-12-19 14:08:01 +000047static bool enable_le;
Andre Guedese6100a22011-06-30 19:20:54 -030048
Linus Torvalds1da177e2005-04-16 15:20:36 -070049/* Handle HCI Event packets */
50
Marcel Holtmanna9de9242007-10-20 13:33:56 +020051static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070052{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020053 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Marcel Holtmanna9de9242007-10-20 13:33:56 +020055 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070056
Andre Guedese6d465c2011-11-09 17:14:26 -030057 if (status) {
58 hci_dev_lock(hdev);
59 mgmt_stop_discovery_failed(hdev, status);
60 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020061 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030062 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Andre Guedes89352e72011-11-04 14:16:53 -030064 clear_bit(HCI_INQUIRY, &hdev->flags);
65
Johan Hedberg56e5cb82011-11-08 20:40:16 +020066 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020067 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020068 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010069
Johan Hedberg23bb5762010-12-21 23:01:27 +020070 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010071
Marcel Holtmanna9de9242007-10-20 13:33:56 +020072 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070073}
74
Marcel Holtmanna9de9242007-10-20 13:33:56 +020075static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070076{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020077 __u8 status = *((__u8 *) skb->data);
78
79 BT_DBG("%s status 0x%x", hdev->name, status);
80
81 if (status)
82 return;
83
Marcel Holtmanna9de9242007-10-20 13:33:56 +020084 hci_conn_check_pending(hdev);
85}
86
87static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
88{
89 BT_DBG("%s", hdev->name);
90}
91
92static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
93{
94 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070098
Marcel Holtmanna9de9242007-10-20 13:33:56 +020099 if (rp->status)
100 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200102 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200104 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
105 if (conn) {
106 if (rp->role)
107 conn->link_mode &= ~HCI_LM_MASTER;
108 else
109 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200111
112 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113}
114
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200115static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
116{
117 struct hci_rp_read_link_policy *rp = (void *) skb->data;
118 struct hci_conn *conn;
119
120 BT_DBG("%s status 0x%x", hdev->name, rp->status);
121
122 if (rp->status)
123 return;
124
125 hci_dev_lock(hdev);
126
127 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
128 if (conn)
129 conn->link_policy = __le16_to_cpu(rp->policy);
130
131 hci_dev_unlock(hdev);
132}
133
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200134static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200136 struct hci_rp_write_link_policy *rp = (void *) skb->data;
137 struct hci_conn *conn;
138 void *sent;
139
140 BT_DBG("%s status 0x%x", hdev->name, rp->status);
141
142 if (rp->status)
143 return;
144
145 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
146 if (!sent)
147 return;
148
149 hci_dev_lock(hdev);
150
151 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200152 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700153 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200154
155 hci_dev_unlock(hdev);
156}
157
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200158static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
159{
160 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
161
162 BT_DBG("%s status 0x%x", hdev->name, rp->status);
163
164 if (rp->status)
165 return;
166
167 hdev->link_policy = __le16_to_cpu(rp->policy);
168}
169
170static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
171{
172 __u8 status = *((__u8 *) skb->data);
173 void *sent;
174
175 BT_DBG("%s status 0x%x", hdev->name, status);
176
177 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
178 if (!sent)
179 return;
180
181 if (!status)
182 hdev->link_policy = get_unaligned_le16(sent);
183
Johan Hedberg23bb5762010-12-21 23:01:27 +0200184 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200185}
186
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200187static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
188{
189 __u8 status = *((__u8 *) skb->data);
190
191 BT_DBG("%s status 0x%x", hdev->name, status);
192
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300193 clear_bit(HCI_RESET, &hdev->flags);
194
Johan Hedberg23bb5762010-12-21 23:01:27 +0200195 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300196
Johan Hedberg7005ff1782012-01-18 16:14:43 +0200197 /* Reset all flags, except persistent ones */
Hemant Gupta95947a32012-01-23 15:36:11 +0530198 hdev->dev_flags &= BIT(HCI_MGMT) | BIT(HCI_SETUP) | BIT(HCI_AUTO_OFF) |
199 BIT(HCI_LINK_KEYS) | BIT(HCI_DEBUG_KEYS);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200200}
201
202static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
203{
204 __u8 status = *((__u8 *) skb->data);
205 void *sent;
206
207 BT_DBG("%s status 0x%x", hdev->name, status);
208
209 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
210 if (!sent)
211 return;
212
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200213 hci_dev_lock(hdev);
214
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200215 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200216 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 if (status == 0)
219 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200220
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200221 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200222}
223
224static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
225{
226 struct hci_rp_read_local_name *rp = (void *) skb->data;
227
228 BT_DBG("%s status 0x%x", hdev->name, rp->status);
229
230 if (rp->status)
231 return;
232
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200233 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200234}
235
236static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
237{
238 __u8 status = *((__u8 *) skb->data);
239 void *sent;
240
241 BT_DBG("%s status 0x%x", hdev->name, status);
242
243 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
244 if (!sent)
245 return;
246
247 if (!status) {
248 __u8 param = *((__u8 *) sent);
249
250 if (param == AUTH_ENABLED)
251 set_bit(HCI_AUTH, &hdev->flags);
252 else
253 clear_bit(HCI_AUTH, &hdev->flags);
254 }
255
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200256 if (test_bit(HCI_MGMT, &hdev->dev_flags))
257 mgmt_auth_enable_complete(hdev, status);
258
Johan Hedberg23bb5762010-12-21 23:01:27 +0200259 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200260}
261
262static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
263{
264 __u8 status = *((__u8 *) skb->data);
265 void *sent;
266
267 BT_DBG("%s status 0x%x", hdev->name, status);
268
269 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
270 if (!sent)
271 return;
272
273 if (!status) {
274 __u8 param = *((__u8 *) sent);
275
276 if (param)
277 set_bit(HCI_ENCRYPT, &hdev->flags);
278 else
279 clear_bit(HCI_ENCRYPT, &hdev->flags);
280 }
281
Johan Hedberg23bb5762010-12-21 23:01:27 +0200282 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200283}
284
285static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
286{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200287 __u8 param, status = *((__u8 *) skb->data);
288 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200289 void *sent;
290
291 BT_DBG("%s status 0x%x", hdev->name, status);
292
293 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
294 if (!sent)
295 return;
296
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200297 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200298
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200299 hci_dev_lock(hdev);
300
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200301 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200302 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200303 hdev->discov_timeout = 0;
304 goto done;
305 }
306
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200307 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
308 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200309
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200310 if (param & SCAN_INQUIRY) {
311 set_bit(HCI_ISCAN, &hdev->flags);
312 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200313 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200314 if (hdev->discov_timeout > 0) {
315 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
316 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
317 to);
318 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200319 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200320 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200321
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200322 if (param & SCAN_PAGE) {
323 set_bit(HCI_PSCAN, &hdev->flags);
324 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200325 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200326 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200327 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200328
329done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200330 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200331 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200332}
333
334static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
335{
336 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
337
338 BT_DBG("%s status 0x%x", hdev->name, rp->status);
339
340 if (rp->status)
341 return;
342
343 memcpy(hdev->dev_class, rp->dev_class, 3);
344
345 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
346 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
347}
348
349static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
350{
351 __u8 status = *((__u8 *) skb->data);
352 void *sent;
353
354 BT_DBG("%s status 0x%x", hdev->name, status);
355
Marcel Holtmannf383f272008-07-14 20:13:47 +0200356 if (status)
357 return;
358
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200359 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
360 if (!sent)
361 return;
362
Marcel Holtmannf383f272008-07-14 20:13:47 +0200363 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200364}
365
366static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
367{
368 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200370
371 BT_DBG("%s status 0x%x", hdev->name, rp->status);
372
373 if (rp->status)
374 return;
375
376 setting = __le16_to_cpu(rp->voice_setting);
377
Marcel Holtmannf383f272008-07-14 20:13:47 +0200378 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200379 return;
380
381 hdev->voice_setting = setting;
382
383 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
384
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200385 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200386 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200387}
388
389static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
390{
391 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200392 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 void *sent;
394
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200395 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396
Marcel Holtmannf383f272008-07-14 20:13:47 +0200397 if (status)
398 return;
399
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200400 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
401 if (!sent)
402 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403
Marcel Holtmannf383f272008-07-14 20:13:47 +0200404 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405
Marcel Holtmannf383f272008-07-14 20:13:47 +0200406 if (hdev->voice_setting == setting)
407 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Marcel Holtmannf383f272008-07-14 20:13:47 +0200409 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
Marcel Holtmannf383f272008-07-14 20:13:47 +0200411 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
412
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200413 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200414 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415}
416
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200417static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200419 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200421 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422
Johan Hedberg23bb5762010-12-21 23:01:27 +0200423 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424}
425
Marcel Holtmann333140b2008-07-14 20:13:48 +0200426static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
427{
428 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
429
430 BT_DBG("%s status 0x%x", hdev->name, rp->status);
431
432 if (rp->status)
433 return;
434
Johan Hedberg84bde9d2012-01-25 14:21:06 +0200435 if (rp->mode)
436 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
437 else
438 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200439}
440
441static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
442{
443 __u8 status = *((__u8 *) skb->data);
444 void *sent;
445
446 BT_DBG("%s status 0x%x", hdev->name, status);
447
448 if (status)
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200449 goto done;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200450
451 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
452 if (!sent)
453 return;
454
Johan Hedberg84bde9d2012-01-25 14:21:06 +0200455 if (*((u8 *) sent))
456 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
457 else
458 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200459
460done:
461 if (test_bit(HCI_MGMT, &hdev->dev_flags))
462 mgmt_ssp_enable_complete(hdev, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200463}
464
Johan Hedbergd5859e22011-01-25 01:19:58 +0200465static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
466{
467 if (hdev->features[6] & LMP_EXT_INQ)
468 return 2;
469
470 if (hdev->features[3] & LMP_RSSI_INQ)
471 return 1;
472
473 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
474 hdev->lmp_subver == 0x0757)
475 return 1;
476
477 if (hdev->manufacturer == 15) {
478 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
479 return 1;
480 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
481 return 1;
482 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
483 return 1;
484 }
485
486 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
487 hdev->lmp_subver == 0x1805)
488 return 1;
489
490 return 0;
491}
492
493static void hci_setup_inquiry_mode(struct hci_dev *hdev)
494{
495 u8 mode;
496
497 mode = hci_get_inquiry_mode(hdev);
498
499 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
500}
501
502static void hci_setup_event_mask(struct hci_dev *hdev)
503{
504 /* The second byte is 0xff instead of 0x9f (two reserved bits
505 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
506 * command otherwise */
507 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
508
Ville Tervo6de6c182011-05-27 11:16:21 +0300509 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
510 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200511 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300512 return;
513
514 events[4] |= 0x01; /* Flow Specification Complete */
515 events[4] |= 0x02; /* Inquiry Result with RSSI */
516 events[4] |= 0x04; /* Read Remote Extended Features Complete */
517 events[5] |= 0x08; /* Synchronous Connection Complete */
518 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200519
520 if (hdev->features[3] & LMP_RSSI_INQ)
521 events[4] |= 0x04; /* Inquiry Result with RSSI */
522
523 if (hdev->features[5] & LMP_SNIFF_SUBR)
524 events[5] |= 0x20; /* Sniff Subrating */
525
526 if (hdev->features[5] & LMP_PAUSE_ENC)
527 events[5] |= 0x80; /* Encryption Key Refresh Complete */
528
529 if (hdev->features[6] & LMP_EXT_INQ)
530 events[5] |= 0x40; /* Extended Inquiry Result */
531
532 if (hdev->features[6] & LMP_NO_FLUSH)
533 events[7] |= 0x01; /* Enhanced Flush Complete */
534
535 if (hdev->features[7] & LMP_LSTO)
536 events[6] |= 0x80; /* Link Supervision Timeout Changed */
537
538 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
539 events[6] |= 0x01; /* IO Capability Request */
540 events[6] |= 0x02; /* IO Capability Response */
541 events[6] |= 0x04; /* User Confirmation Request */
542 events[6] |= 0x08; /* User Passkey Request */
543 events[6] |= 0x10; /* Remote OOB Data Request */
544 events[6] |= 0x20; /* Simple Pairing Complete */
545 events[7] |= 0x04; /* User Passkey Notification */
546 events[7] |= 0x08; /* Keypress Notification */
547 events[7] |= 0x10; /* Remote Host Supported
548 * Features Notification */
549 }
550
551 if (hdev->features[4] & LMP_LE)
552 events[7] |= 0x20; /* LE Meta-Event */
553
554 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
555}
556
Andre Guedese6100a22011-06-30 19:20:54 -0300557static void hci_set_le_support(struct hci_dev *hdev)
558{
559 struct hci_cp_write_le_host_supported cp;
560
561 memset(&cp, 0, sizeof(cp));
562
563 if (enable_le) {
564 cp.le = 1;
565 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
566 }
567
568 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
569}
570
Johan Hedbergd5859e22011-01-25 01:19:58 +0200571static void hci_setup(struct hci_dev *hdev)
572{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200573 if (hdev->dev_type != HCI_BREDR)
574 return;
575
Johan Hedbergd5859e22011-01-25 01:19:58 +0200576 hci_setup_event_mask(hdev);
577
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200578 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200579 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
580
581 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
582 u8 mode = 0x01;
583 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
584 }
585
586 if (hdev->features[3] & LMP_RSSI_INQ)
587 hci_setup_inquiry_mode(hdev);
588
589 if (hdev->features[7] & LMP_INQ_TX_PWR)
590 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300591
592 if (hdev->features[7] & LMP_EXTFEATURES) {
593 struct hci_cp_read_local_ext_features cp;
594
595 cp.page = 0x01;
596 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
597 sizeof(cp), &cp);
598 }
Andre Guedese6100a22011-06-30 19:20:54 -0300599
600 if (hdev->features[4] & LMP_LE)
601 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200602}
603
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200604static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
605{
606 struct hci_rp_read_local_version *rp = (void *) skb->data;
607
608 BT_DBG("%s status 0x%x", hdev->name, rp->status);
609
610 if (rp->status)
611 return;
612
613 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200614 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200615 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200616 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200617 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200618
619 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
620 hdev->manufacturer,
621 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200622
623 if (test_bit(HCI_INIT, &hdev->flags))
624 hci_setup(hdev);
625}
626
627static void hci_setup_link_policy(struct hci_dev *hdev)
628{
629 u16 link_policy = 0;
630
631 if (hdev->features[0] & LMP_RSWITCH)
632 link_policy |= HCI_LP_RSWITCH;
633 if (hdev->features[0] & LMP_HOLD)
634 link_policy |= HCI_LP_HOLD;
635 if (hdev->features[0] & LMP_SNIFF)
636 link_policy |= HCI_LP_SNIFF;
637 if (hdev->features[1] & LMP_PARK)
638 link_policy |= HCI_LP_PARK;
639
640 link_policy = cpu_to_le16(link_policy);
641 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
642 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200643}
644
645static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
646{
647 struct hci_rp_read_local_commands *rp = (void *) skb->data;
648
649 BT_DBG("%s status 0x%x", hdev->name, rp->status);
650
651 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200652 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200653
654 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200655
656 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
657 hci_setup_link_policy(hdev);
658
659done:
660 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200661}
662
663static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
664{
665 struct hci_rp_read_local_features *rp = (void *) skb->data;
666
667 BT_DBG("%s status 0x%x", hdev->name, rp->status);
668
669 if (rp->status)
670 return;
671
672 memcpy(hdev->features, rp->features, 8);
673
674 /* Adjust default settings according to features
675 * supported by device. */
676
677 if (hdev->features[0] & LMP_3SLOT)
678 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
679
680 if (hdev->features[0] & LMP_5SLOT)
681 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
682
683 if (hdev->features[1] & LMP_HV2) {
684 hdev->pkt_type |= (HCI_HV2);
685 hdev->esco_type |= (ESCO_HV2);
686 }
687
688 if (hdev->features[1] & LMP_HV3) {
689 hdev->pkt_type |= (HCI_HV3);
690 hdev->esco_type |= (ESCO_HV3);
691 }
692
693 if (hdev->features[3] & LMP_ESCO)
694 hdev->esco_type |= (ESCO_EV3);
695
696 if (hdev->features[4] & LMP_EV4)
697 hdev->esco_type |= (ESCO_EV4);
698
699 if (hdev->features[4] & LMP_EV5)
700 hdev->esco_type |= (ESCO_EV5);
701
Marcel Holtmannefc76882009-02-06 09:13:37 +0100702 if (hdev->features[5] & LMP_EDR_ESCO_2M)
703 hdev->esco_type |= (ESCO_2EV3);
704
705 if (hdev->features[5] & LMP_EDR_ESCO_3M)
706 hdev->esco_type |= (ESCO_3EV3);
707
708 if (hdev->features[5] & LMP_EDR_3S_ESCO)
709 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
710
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200711 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
712 hdev->features[0], hdev->features[1],
713 hdev->features[2], hdev->features[3],
714 hdev->features[4], hdev->features[5],
715 hdev->features[6], hdev->features[7]);
716}
717
Andre Guedes971e3a42011-06-30 19:20:52 -0300718static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
719 struct sk_buff *skb)
720{
721 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
722
723 BT_DBG("%s status 0x%x", hdev->name, rp->status);
724
725 if (rp->status)
726 return;
727
Andre Guedesb5b32b62011-12-30 10:34:04 -0300728 switch (rp->page) {
729 case 0:
730 memcpy(hdev->features, rp->features, 8);
731 break;
732 case 1:
733 memcpy(hdev->host_features, rp->features, 8);
734 break;
735 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300736
737 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
738}
739
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200740static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
741 struct sk_buff *skb)
742{
743 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
744
745 BT_DBG("%s status 0x%x", hdev->name, rp->status);
746
747 if (rp->status)
748 return;
749
750 hdev->flow_ctl_mode = rp->mode;
751
752 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
753}
754
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200755static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
756{
757 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
758
759 BT_DBG("%s status 0x%x", hdev->name, rp->status);
760
761 if (rp->status)
762 return;
763
764 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
765 hdev->sco_mtu = rp->sco_mtu;
766 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
767 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
768
769 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
770 hdev->sco_mtu = 64;
771 hdev->sco_pkts = 8;
772 }
773
774 hdev->acl_cnt = hdev->acl_pkts;
775 hdev->sco_cnt = hdev->sco_pkts;
776
777 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
778 hdev->acl_mtu, hdev->acl_pkts,
779 hdev->sco_mtu, hdev->sco_pkts);
780}
781
782static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
783{
784 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
785
786 BT_DBG("%s status 0x%x", hdev->name, rp->status);
787
788 if (!rp->status)
789 bacpy(&hdev->bdaddr, &rp->bdaddr);
790
Johan Hedberg23bb5762010-12-21 23:01:27 +0200791 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
792}
793
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200794static void hci_cc_read_data_block_size(struct hci_dev *hdev,
795 struct sk_buff *skb)
796{
797 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
798
799 BT_DBG("%s status 0x%x", hdev->name, rp->status);
800
801 if (rp->status)
802 return;
803
804 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
805 hdev->block_len = __le16_to_cpu(rp->block_len);
806 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
807
808 hdev->block_cnt = hdev->num_blocks;
809
810 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
811 hdev->block_cnt, hdev->block_len);
812
813 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
814}
815
Johan Hedberg23bb5762010-12-21 23:01:27 +0200816static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
817{
818 __u8 status = *((__u8 *) skb->data);
819
820 BT_DBG("%s status 0x%x", hdev->name, status);
821
822 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200823}
824
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300825static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
826 struct sk_buff *skb)
827{
828 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
829
830 BT_DBG("%s status 0x%x", hdev->name, rp->status);
831
832 if (rp->status)
833 return;
834
835 hdev->amp_status = rp->amp_status;
836 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
837 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
838 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
839 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
840 hdev->amp_type = rp->amp_type;
841 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
842 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
843 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
844 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
845
846 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
847}
848
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200849static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
850 struct sk_buff *skb)
851{
852 __u8 status = *((__u8 *) skb->data);
853
854 BT_DBG("%s status 0x%x", hdev->name, status);
855
856 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
857}
858
Johan Hedbergd5859e22011-01-25 01:19:58 +0200859static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
860{
861 __u8 status = *((__u8 *) skb->data);
862
863 BT_DBG("%s status 0x%x", hdev->name, status);
864
865 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
866}
867
868static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
869 struct sk_buff *skb)
870{
871 __u8 status = *((__u8 *) skb->data);
872
873 BT_DBG("%s status 0x%x", hdev->name, status);
874
875 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
876}
877
878static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
879 struct sk_buff *skb)
880{
881 __u8 status = *((__u8 *) skb->data);
882
883 BT_DBG("%s status 0x%x", hdev->name, status);
884
885 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
886}
887
888static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
889{
890 __u8 status = *((__u8 *) skb->data);
891
892 BT_DBG("%s status 0x%x", hdev->name, status);
893
894 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
895}
896
Johan Hedberg980e1a52011-01-22 06:10:07 +0200897static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
898{
899 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
900 struct hci_cp_pin_code_reply *cp;
901 struct hci_conn *conn;
902
903 BT_DBG("%s status 0x%x", hdev->name, rp->status);
904
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200905 hci_dev_lock(hdev);
906
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200907 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200908 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200909
910 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200911 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200912
913 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
914 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200915 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200916
917 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
918 if (conn)
919 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200920
921unlock:
922 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200923}
924
925static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
926{
927 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
928
929 BT_DBG("%s status 0x%x", hdev->name, rp->status);
930
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200931 hci_dev_lock(hdev);
932
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200933 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200934 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200935 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200936
937 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200938}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200939
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300940static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
941 struct sk_buff *skb)
942{
943 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
944
945 BT_DBG("%s status 0x%x", hdev->name, rp->status);
946
947 if (rp->status)
948 return;
949
950 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
951 hdev->le_pkts = rp->le_max_pkt;
952
953 hdev->le_cnt = hdev->le_pkts;
954
955 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
956
957 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
958}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200959
Johan Hedberga5c29682011-02-19 12:05:57 -0300960static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
961{
962 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
963
964 BT_DBG("%s status 0x%x", hdev->name, rp->status);
965
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200966 hci_dev_lock(hdev);
967
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200968 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200969 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
970 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200971
972 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300973}
974
975static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
976 struct sk_buff *skb)
977{
978 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
979
980 BT_DBG("%s status 0x%x", hdev->name, rp->status);
981
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200982 hci_dev_lock(hdev);
983
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200984 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200985 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200986 ACL_LINK, 0,
Johan Hedberga5c29682011-02-19 12:05:57 -0300987 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200988
989 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300990}
991
Brian Gix1143d452011-11-23 08:28:34 -0800992static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
993{
994 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
995
996 BT_DBG("%s status 0x%x", hdev->name, rp->status);
997
998 hci_dev_lock(hdev);
999
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001000 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001001 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1002 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001003
1004 hci_dev_unlock(hdev);
1005}
1006
1007static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1008 struct sk_buff *skb)
1009{
1010 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1011
1012 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1013
1014 hci_dev_lock(hdev);
1015
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001016 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001017 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001018 ACL_LINK, 0,
Brian Gix1143d452011-11-23 08:28:34 -08001019 rp->status);
1020
1021 hci_dev_unlock(hdev);
1022}
1023
Szymon Jancc35938b2011-03-22 13:12:21 +01001024static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1025 struct sk_buff *skb)
1026{
1027 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1028
1029 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1030
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001031 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001032 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001033 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001034 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001035}
1036
Andre Guedes07f7fa52011-12-02 21:13:31 +09001037static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1038{
1039 __u8 status = *((__u8 *) skb->data);
1040
1041 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001042
1043 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001044
1045 if (status) {
1046 hci_dev_lock(hdev);
1047 mgmt_start_discovery_failed(hdev, status);
1048 hci_dev_unlock(hdev);
1049 return;
1050 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001051}
1052
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001053static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1054 struct sk_buff *skb)
1055{
1056 struct hci_cp_le_set_scan_enable *cp;
1057 __u8 status = *((__u8 *) skb->data);
1058
1059 BT_DBG("%s status 0x%x", hdev->name, status);
1060
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001061 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1062 if (!cp)
1063 return;
1064
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001065 switch (cp->enable) {
1066 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001067 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1068
Andre Guedes3fd24152012-02-03 17:48:01 -03001069 if (status) {
1070 hci_dev_lock(hdev);
1071 mgmt_start_discovery_failed(hdev, status);
1072 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001073 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001074 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001075
Andre Guedesd23264a2011-11-25 20:53:38 -03001076 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1077
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001078 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001079
1080 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001081 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001082 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001083 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001084 break;
1085
1086 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001087 if (status)
1088 return;
1089
Andre Guedesd23264a2011-11-25 20:53:38 -03001090 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1091
Andre Guedesd0843292012-01-02 19:18:11 -03001092 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001093
1094 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1095 mgmt_interleaved_discovery(hdev);
1096 } else {
1097 hci_dev_lock(hdev);
1098 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1099 hci_dev_unlock(hdev);
1100 }
1101
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001102 break;
1103
1104 default:
1105 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1106 break;
Andre Guedes35815082011-05-26 16:23:53 -03001107 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001108}
1109
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001110static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1111{
1112 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1113
1114 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1115
1116 if (rp->status)
1117 return;
1118
1119 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1120}
1121
1122static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1123{
1124 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1125
1126 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1127
1128 if (rp->status)
1129 return;
1130
1131 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1132}
1133
Andre Guedesf9b49302011-06-30 19:20:53 -03001134static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1135 struct sk_buff *skb)
1136{
1137 struct hci_cp_read_local_ext_features cp;
1138 __u8 status = *((__u8 *) skb->data);
1139
1140 BT_DBG("%s status 0x%x", hdev->name, status);
1141
1142 if (status)
1143 return;
1144
1145 cp.page = 0x01;
1146 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1147}
1148
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001149static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1150{
1151 BT_DBG("%s status 0x%x", hdev->name, status);
1152
1153 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001154 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001155 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001156 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001157 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001158 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001159 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001160 return;
1161 }
1162
Andre Guedes89352e72011-11-04 14:16:53 -03001163 set_bit(HCI_INQUIRY, &hdev->flags);
1164
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001165 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001166 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001167 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001168}
1169
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1171{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001172 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001175 BT_DBG("%s status 0x%x", hdev->name, status);
1176
1177 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 if (!cp)
1179 return;
1180
1181 hci_dev_lock(hdev);
1182
1183 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1184
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001185 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186
1187 if (status) {
1188 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001189 if (status != 0x0c || conn->attempt > 2) {
1190 conn->state = BT_CLOSED;
1191 hci_proto_connect_cfm(conn, status);
1192 hci_conn_del(conn);
1193 } else
1194 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 }
1196 } else {
1197 if (!conn) {
1198 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1199 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001200 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201 conn->link_mode |= HCI_LM_MASTER;
1202 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001203 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 }
1205 }
1206
1207 hci_dev_unlock(hdev);
1208}
1209
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001210static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001212 struct hci_cp_add_sco *cp;
1213 struct hci_conn *acl, *sco;
1214 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001216 BT_DBG("%s status 0x%x", hdev->name, status);
1217
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001218 if (!status)
1219 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001221 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1222 if (!cp)
1223 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001225 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001227 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001228
1229 hci_dev_lock(hdev);
1230
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001231 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001232 if (acl) {
1233 sco = acl->link;
1234 if (sco) {
1235 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001236
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001237 hci_proto_connect_cfm(sco, status);
1238 hci_conn_del(sco);
1239 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001240 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001241
1242 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243}
1244
Marcel Holtmannf8558552008-07-14 20:13:49 +02001245static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1246{
1247 struct hci_cp_auth_requested *cp;
1248 struct hci_conn *conn;
1249
1250 BT_DBG("%s status 0x%x", hdev->name, status);
1251
1252 if (!status)
1253 return;
1254
1255 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1256 if (!cp)
1257 return;
1258
1259 hci_dev_lock(hdev);
1260
1261 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1262 if (conn) {
1263 if (conn->state == BT_CONFIG) {
1264 hci_proto_connect_cfm(conn, status);
1265 hci_conn_put(conn);
1266 }
1267 }
1268
1269 hci_dev_unlock(hdev);
1270}
1271
1272static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1273{
1274 struct hci_cp_set_conn_encrypt *cp;
1275 struct hci_conn *conn;
1276
1277 BT_DBG("%s status 0x%x", hdev->name, status);
1278
1279 if (!status)
1280 return;
1281
1282 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1283 if (!cp)
1284 return;
1285
1286 hci_dev_lock(hdev);
1287
1288 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1289 if (conn) {
1290 if (conn->state == BT_CONFIG) {
1291 hci_proto_connect_cfm(conn, status);
1292 hci_conn_put(conn);
1293 }
1294 }
1295
1296 hci_dev_unlock(hdev);
1297}
1298
Johan Hedberg127178d2010-11-18 22:22:29 +02001299static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001300 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001301{
Johan Hedberg392599b2010-11-18 22:22:28 +02001302 if (conn->state != BT_CONFIG || !conn->out)
1303 return 0;
1304
Johan Hedberg765c2a92011-01-19 12:06:52 +05301305 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001306 return 0;
1307
1308 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001309 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001310 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001311 conn->pending_sec_level != BT_SECURITY_HIGH &&
1312 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001313 return 0;
1314
Johan Hedberg392599b2010-11-18 22:22:28 +02001315 return 1;
1316}
1317
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001318static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1319{
1320 struct hci_cp_remote_name_req cp;
1321
1322 memset(&cp, 0, sizeof(cp));
1323
1324 bacpy(&cp.bdaddr, &e->data.bdaddr);
1325 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1326 cp.pscan_mode = e->data.pscan_mode;
1327 cp.clock_offset = e->data.clock_offset;
1328
1329 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1330}
1331
Johan Hedbergb644ba32012-01-17 21:48:47 +02001332static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001333{
1334 struct discovery_state *discov = &hdev->discovery;
1335 struct inquiry_entry *e;
1336
Johan Hedbergb644ba32012-01-17 21:48:47 +02001337 if (list_empty(&discov->resolve))
1338 return false;
1339
1340 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1341 if (hci_resolve_name(hdev, e) == 0) {
1342 e->name_state = NAME_PENDING;
1343 return true;
1344 }
1345
1346 return false;
1347}
1348
1349static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1350 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1351{
1352 struct discovery_state *discov = &hdev->discovery;
1353 struct inquiry_entry *e;
1354
1355 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1356 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
1357 name, name_len, conn->dev_class);
1358
1359 if (discov->state == DISCOVERY_STOPPED)
1360 return;
1361
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001362 if (discov->state == DISCOVERY_STOPPING)
1363 goto discov_complete;
1364
1365 if (discov->state != DISCOVERY_RESOLVING)
1366 return;
1367
1368 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1369 if (e) {
1370 e->name_state = NAME_KNOWN;
1371 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001372 if (name)
1373 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1374 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001375 }
1376
Johan Hedbergb644ba32012-01-17 21:48:47 +02001377 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001378 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001379
1380discov_complete:
1381 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1382}
1383
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001384static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1385{
Johan Hedberg127178d2010-11-18 22:22:29 +02001386 struct hci_cp_remote_name_req *cp;
1387 struct hci_conn *conn;
1388
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001389 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001390
1391 /* If successful wait for the name req complete event before
1392 * checking for the need to do authentication */
1393 if (!status)
1394 return;
1395
1396 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1397 if (!cp)
1398 return;
1399
1400 hci_dev_lock(hdev);
1401
1402 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001403
1404 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1405 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1406
Johan Hedberg79c6c702011-04-28 11:28:55 -07001407 if (!conn)
1408 goto unlock;
1409
1410 if (!hci_outgoing_auth_needed(hdev, conn))
1411 goto unlock;
1412
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001413 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001414 struct hci_cp_auth_requested cp;
1415 cp.handle = __cpu_to_le16(conn->handle);
1416 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1417 }
1418
Johan Hedberg79c6c702011-04-28 11:28:55 -07001419unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001420 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001421}
1422
Marcel Holtmann769be972008-07-14 20:13:49 +02001423static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1424{
1425 struct hci_cp_read_remote_features *cp;
1426 struct hci_conn *conn;
1427
1428 BT_DBG("%s status 0x%x", hdev->name, status);
1429
1430 if (!status)
1431 return;
1432
1433 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1434 if (!cp)
1435 return;
1436
1437 hci_dev_lock(hdev);
1438
1439 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1440 if (conn) {
1441 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001442 hci_proto_connect_cfm(conn, status);
1443 hci_conn_put(conn);
1444 }
1445 }
1446
1447 hci_dev_unlock(hdev);
1448}
1449
1450static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1451{
1452 struct hci_cp_read_remote_ext_features *cp;
1453 struct hci_conn *conn;
1454
1455 BT_DBG("%s status 0x%x", hdev->name, status);
1456
1457 if (!status)
1458 return;
1459
1460 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1461 if (!cp)
1462 return;
1463
1464 hci_dev_lock(hdev);
1465
1466 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1467 if (conn) {
1468 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001469 hci_proto_connect_cfm(conn, status);
1470 hci_conn_put(conn);
1471 }
1472 }
1473
1474 hci_dev_unlock(hdev);
1475}
1476
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001477static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1478{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001479 struct hci_cp_setup_sync_conn *cp;
1480 struct hci_conn *acl, *sco;
1481 __u16 handle;
1482
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001483 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001484
1485 if (!status)
1486 return;
1487
1488 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1489 if (!cp)
1490 return;
1491
1492 handle = __le16_to_cpu(cp->handle);
1493
1494 BT_DBG("%s handle %d", hdev->name, handle);
1495
1496 hci_dev_lock(hdev);
1497
1498 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001499 if (acl) {
1500 sco = acl->link;
1501 if (sco) {
1502 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001503
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001504 hci_proto_connect_cfm(sco, status);
1505 hci_conn_del(sco);
1506 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001507 }
1508
1509 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001510}
1511
1512static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1513{
1514 struct hci_cp_sniff_mode *cp;
1515 struct hci_conn *conn;
1516
1517 BT_DBG("%s status 0x%x", hdev->name, status);
1518
1519 if (!status)
1520 return;
1521
1522 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1523 if (!cp)
1524 return;
1525
1526 hci_dev_lock(hdev);
1527
1528 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001529 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001530 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001531
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001532 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001533 hci_sco_setup(conn, status);
1534 }
1535
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001536 hci_dev_unlock(hdev);
1537}
1538
1539static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1540{
1541 struct hci_cp_exit_sniff_mode *cp;
1542 struct hci_conn *conn;
1543
1544 BT_DBG("%s status 0x%x", hdev->name, status);
1545
1546 if (!status)
1547 return;
1548
1549 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1550 if (!cp)
1551 return;
1552
1553 hci_dev_lock(hdev);
1554
1555 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001556 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001557 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001558
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001559 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001560 hci_sco_setup(conn, status);
1561 }
1562
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001563 hci_dev_unlock(hdev);
1564}
1565
Johan Hedberg88c3df12012-02-09 14:27:38 +02001566static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1567{
1568 struct hci_cp_disconnect *cp;
1569 struct hci_conn *conn;
1570
1571 if (!status)
1572 return;
1573
1574 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1575 if (!cp)
1576 return;
1577
1578 hci_dev_lock(hdev);
1579
1580 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1581 if (conn)
1582 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1583 conn->dst_type, status);
1584
1585 hci_dev_unlock(hdev);
1586}
1587
Ville Tervofcd89c02011-02-10 22:38:47 -03001588static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1589{
1590 struct hci_cp_le_create_conn *cp;
1591 struct hci_conn *conn;
1592
1593 BT_DBG("%s status 0x%x", hdev->name, status);
1594
1595 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1596 if (!cp)
1597 return;
1598
1599 hci_dev_lock(hdev);
1600
1601 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1602
1603 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1604 conn);
1605
1606 if (status) {
1607 if (conn && conn->state == BT_CONNECT) {
1608 conn->state = BT_CLOSED;
1609 hci_proto_connect_cfm(conn, status);
1610 hci_conn_del(conn);
1611 }
1612 } else {
1613 if (!conn) {
1614 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001615 if (conn) {
1616 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001617 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001618 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001619 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001620 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001621 }
1622 }
1623
1624 hci_dev_unlock(hdev);
1625}
1626
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001627static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1628{
1629 BT_DBG("%s status 0x%x", hdev->name, status);
1630}
1631
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001632static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1633{
1634 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001635 struct discovery_state *discov = &hdev->discovery;
1636 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001637
1638 BT_DBG("%s status %d", hdev->name, status);
1639
Johan Hedberg23bb5762010-12-21 23:01:27 +02001640 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001641
1642 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001643
1644 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1645 return;
1646
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001647 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001648 return;
1649
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001650 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001651
Andre Guedes343f9352012-02-17 20:39:37 -03001652 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001653 goto unlock;
1654
1655 if (list_empty(&discov->resolve)) {
1656 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1657 goto unlock;
1658 }
1659
1660 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1661 if (e && hci_resolve_name(hdev, e) == 0) {
1662 e->name_state = NAME_PENDING;
1663 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1664 } else {
1665 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1666 }
1667
1668unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001669 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001670}
1671
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1673{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001674 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001675 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 int num_rsp = *((__u8 *) skb->data);
1677
1678 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1679
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001680 if (!num_rsp)
1681 return;
1682
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001684
Johan Hedberge17acd42011-03-30 23:57:16 +03001685 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg31754052012-01-04 13:39:52 +02001686 bool name_known;
1687
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 bacpy(&data.bdaddr, &info->bdaddr);
1689 data.pscan_rep_mode = info->pscan_rep_mode;
1690 data.pscan_period_mode = info->pscan_period_mode;
1691 data.pscan_mode = info->pscan_mode;
1692 memcpy(data.dev_class, info->dev_class, 3);
1693 data.clock_offset = info->clock_offset;
1694 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001695 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001696
1697 name_known = hci_inquiry_cache_update(hdev, &data, false);
Johan Hedberg48264f02011-11-09 13:58:58 +02001698 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Andre Guedes7d262f82012-01-10 18:20:49 -03001699 info->dev_class, 0, !name_known,
1700 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001702
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 hci_dev_unlock(hdev);
1704}
1705
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001706static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001708 struct hci_ev_conn_complete *ev = (void *) skb->data;
1709 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001711 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001712
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001714
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001715 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001716 if (!conn) {
1717 if (ev->link_type != SCO_LINK)
1718 goto unlock;
1719
1720 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1721 if (!conn)
1722 goto unlock;
1723
1724 conn->type = SCO_LINK;
1725 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001726
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001727 if (!ev->status) {
1728 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001729
1730 if (conn->type == ACL_LINK) {
1731 conn->state = BT_CONFIG;
1732 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001733 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001734 } else
1735 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001736
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001737 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001738 hci_conn_add_sysfs(conn);
1739
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001740 if (test_bit(HCI_AUTH, &hdev->flags))
1741 conn->link_mode |= HCI_LM_AUTH;
1742
1743 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1744 conn->link_mode |= HCI_LM_ENCRYPT;
1745
1746 /* Get remote features */
1747 if (conn->type == ACL_LINK) {
1748 struct hci_cp_read_remote_features cp;
1749 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001750 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1751 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001752 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001753
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001754 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001755 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001756 struct hci_cp_change_conn_ptype cp;
1757 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001758 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1759 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1760 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001761 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001762 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001763 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001764 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001765 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001766 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001767 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001768
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001769 if (conn->type == ACL_LINK)
1770 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001771
Marcel Holtmann769be972008-07-14 20:13:49 +02001772 if (ev->status) {
1773 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001774 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001775 } else if (ev->link_type != ACL_LINK)
1776 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001777
1778unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001780
1781 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782}
1783
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1785{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001786 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 int mask = hdev->link_mode;
1788
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001789 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1790 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791
1792 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1793
Szymon Janc138d22e2011-02-17 16:44:23 +01001794 if ((mask & HCI_LM_ACCEPT) &&
1795 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001797 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799
1800 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001801
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001802 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1803 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001804 memcpy(ie->data.dev_class, ev->dev_class, 3);
1805
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1807 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001808 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1809 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001810 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 hci_dev_unlock(hdev);
1812 return;
1813 }
1814 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001815
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 memcpy(conn->dev_class, ev->dev_class, 3);
1817 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001818
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 hci_dev_unlock(hdev);
1820
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001821 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1822 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001824 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001826 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1827 cp.role = 0x00; /* Become master */
1828 else
1829 cp.role = 0x01; /* Remain slave */
1830
1831 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1832 sizeof(cp), &cp);
1833 } else {
1834 struct hci_cp_accept_sync_conn_req cp;
1835
1836 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001837 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001838
1839 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1840 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1841 cp.max_latency = cpu_to_le16(0xffff);
1842 cp.content_format = cpu_to_le16(hdev->voice_setting);
1843 cp.retrans_effort = 0xff;
1844
1845 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1846 sizeof(cp), &cp);
1847 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 } else {
1849 /* Connection rejected */
1850 struct hci_cp_reject_conn_req cp;
1851
1852 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001853 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001854 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855 }
1856}
1857
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1859{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001860 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001861 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
1863 BT_DBG("%s status %d", hdev->name, ev->status);
1864
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 hci_dev_lock(hdev);
1866
Marcel Holtmann04837f62006-07-03 10:02:33 +02001867 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001868 if (!conn)
1869 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001870
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001871 if (ev->status == 0)
1872 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
Johan Hedbergb644ba32012-01-17 21:48:47 +02001874 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1875 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001876 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001877 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1878 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001879 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001880 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001881 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001882 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001883
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001884 if (ev->status == 0) {
1885 hci_proto_disconn_cfm(conn, ev->reason);
1886 hci_conn_del(conn);
1887 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001888
1889unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 hci_dev_unlock(hdev);
1891}
1892
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001893static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1894{
1895 struct hci_ev_auth_complete *ev = (void *) skb->data;
1896 struct hci_conn *conn;
1897
1898 BT_DBG("%s status %d", hdev->name, ev->status);
1899
1900 hci_dev_lock(hdev);
1901
1902 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001903 if (!conn)
1904 goto unlock;
1905
1906 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001907 if (!hci_conn_ssp_enabled(conn) &&
1908 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001909 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001910 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001911 conn->link_mode |= HCI_LM_AUTH;
1912 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001913 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001914 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001915 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
1916 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001917 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001918
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001919 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1920 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001921
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001922 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001923 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001924 struct hci_cp_set_conn_encrypt cp;
1925 cp.handle = ev->handle;
1926 cp.encrypt = 0x01;
1927 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1928 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001929 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001930 conn->state = BT_CONNECTED;
1931 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001932 hci_conn_put(conn);
1933 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001934 } else {
1935 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001936
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001937 hci_conn_hold(conn);
1938 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1939 hci_conn_put(conn);
1940 }
1941
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001942 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001943 if (!ev->status) {
1944 struct hci_cp_set_conn_encrypt cp;
1945 cp.handle = ev->handle;
1946 cp.encrypt = 0x01;
1947 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1948 &cp);
1949 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001950 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001951 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001952 }
1953 }
1954
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001955unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001956 hci_dev_unlock(hdev);
1957}
1958
1959static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1960{
Johan Hedberg127178d2010-11-18 22:22:29 +02001961 struct hci_ev_remote_name *ev = (void *) skb->data;
1962 struct hci_conn *conn;
1963
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001964 BT_DBG("%s", hdev->name);
1965
1966 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001967
1968 hci_dev_lock(hdev);
1969
1970 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001971
1972 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1973 goto check_auth;
1974
1975 if (ev->status == 0)
1976 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1977 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1978 else
1979 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1980
1981check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001982 if (!conn)
1983 goto unlock;
1984
1985 if (!hci_outgoing_auth_needed(hdev, conn))
1986 goto unlock;
1987
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001988 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001989 struct hci_cp_auth_requested cp;
1990 cp.handle = __cpu_to_le16(conn->handle);
1991 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1992 }
1993
Johan Hedberg79c6c702011-04-28 11:28:55 -07001994unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001995 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001996}
1997
1998static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1999{
2000 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2001 struct hci_conn *conn;
2002
2003 BT_DBG("%s status %d", hdev->name, ev->status);
2004
2005 hci_dev_lock(hdev);
2006
2007 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2008 if (conn) {
2009 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002010 if (ev->encrypt) {
2011 /* Encryption implies authentication */
2012 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002013 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002014 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002015 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002016 conn->link_mode &= ~HCI_LM_ENCRYPT;
2017 }
2018
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002019 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002020
Marcel Holtmannf8558552008-07-14 20:13:49 +02002021 if (conn->state == BT_CONFIG) {
2022 if (!ev->status)
2023 conn->state = BT_CONNECTED;
2024
2025 hci_proto_connect_cfm(conn, ev->status);
2026 hci_conn_put(conn);
2027 } else
2028 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002029 }
2030
2031 hci_dev_unlock(hdev);
2032}
2033
2034static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2035{
2036 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2037 struct hci_conn *conn;
2038
2039 BT_DBG("%s status %d", hdev->name, ev->status);
2040
2041 hci_dev_lock(hdev);
2042
2043 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2044 if (conn) {
2045 if (!ev->status)
2046 conn->link_mode |= HCI_LM_SECURE;
2047
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002048 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002049
2050 hci_key_change_cfm(conn, ev->status);
2051 }
2052
2053 hci_dev_unlock(hdev);
2054}
2055
2056static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2057{
2058 struct hci_ev_remote_features *ev = (void *) skb->data;
2059 struct hci_conn *conn;
2060
2061 BT_DBG("%s status %d", hdev->name, ev->status);
2062
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002063 hci_dev_lock(hdev);
2064
2065 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002066 if (!conn)
2067 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002068
Johan Hedbergccd556f2010-11-10 17:11:51 +02002069 if (!ev->status)
2070 memcpy(conn->features, ev->features, 8);
2071
2072 if (conn->state != BT_CONFIG)
2073 goto unlock;
2074
2075 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2076 struct hci_cp_read_remote_ext_features cp;
2077 cp.handle = ev->handle;
2078 cp.page = 0x01;
2079 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002080 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002081 goto unlock;
2082 }
2083
Johan Hedberg127178d2010-11-18 22:22:29 +02002084 if (!ev->status) {
2085 struct hci_cp_remote_name_req cp;
2086 memset(&cp, 0, sizeof(cp));
2087 bacpy(&cp.bdaddr, &conn->dst);
2088 cp.pscan_rep_mode = 0x02;
2089 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002090 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2091 mgmt_device_connected(hdev, &conn->dst, conn->type,
2092 conn->dst_type, NULL, 0,
2093 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002094
Johan Hedberg127178d2010-11-18 22:22:29 +02002095 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002096 conn->state = BT_CONNECTED;
2097 hci_proto_connect_cfm(conn, ev->status);
2098 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002099 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002100
Johan Hedbergccd556f2010-11-10 17:11:51 +02002101unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002102 hci_dev_unlock(hdev);
2103}
2104
2105static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2106{
2107 BT_DBG("%s", hdev->name);
2108}
2109
2110static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2111{
2112 BT_DBG("%s", hdev->name);
2113}
2114
2115static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2116{
2117 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2118 __u16 opcode;
2119
2120 skb_pull(skb, sizeof(*ev));
2121
2122 opcode = __le16_to_cpu(ev->opcode);
2123
2124 switch (opcode) {
2125 case HCI_OP_INQUIRY_CANCEL:
2126 hci_cc_inquiry_cancel(hdev, skb);
2127 break;
2128
2129 case HCI_OP_EXIT_PERIODIC_INQ:
2130 hci_cc_exit_periodic_inq(hdev, skb);
2131 break;
2132
2133 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2134 hci_cc_remote_name_req_cancel(hdev, skb);
2135 break;
2136
2137 case HCI_OP_ROLE_DISCOVERY:
2138 hci_cc_role_discovery(hdev, skb);
2139 break;
2140
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002141 case HCI_OP_READ_LINK_POLICY:
2142 hci_cc_read_link_policy(hdev, skb);
2143 break;
2144
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002145 case HCI_OP_WRITE_LINK_POLICY:
2146 hci_cc_write_link_policy(hdev, skb);
2147 break;
2148
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002149 case HCI_OP_READ_DEF_LINK_POLICY:
2150 hci_cc_read_def_link_policy(hdev, skb);
2151 break;
2152
2153 case HCI_OP_WRITE_DEF_LINK_POLICY:
2154 hci_cc_write_def_link_policy(hdev, skb);
2155 break;
2156
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002157 case HCI_OP_RESET:
2158 hci_cc_reset(hdev, skb);
2159 break;
2160
2161 case HCI_OP_WRITE_LOCAL_NAME:
2162 hci_cc_write_local_name(hdev, skb);
2163 break;
2164
2165 case HCI_OP_READ_LOCAL_NAME:
2166 hci_cc_read_local_name(hdev, skb);
2167 break;
2168
2169 case HCI_OP_WRITE_AUTH_ENABLE:
2170 hci_cc_write_auth_enable(hdev, skb);
2171 break;
2172
2173 case HCI_OP_WRITE_ENCRYPT_MODE:
2174 hci_cc_write_encrypt_mode(hdev, skb);
2175 break;
2176
2177 case HCI_OP_WRITE_SCAN_ENABLE:
2178 hci_cc_write_scan_enable(hdev, skb);
2179 break;
2180
2181 case HCI_OP_READ_CLASS_OF_DEV:
2182 hci_cc_read_class_of_dev(hdev, skb);
2183 break;
2184
2185 case HCI_OP_WRITE_CLASS_OF_DEV:
2186 hci_cc_write_class_of_dev(hdev, skb);
2187 break;
2188
2189 case HCI_OP_READ_VOICE_SETTING:
2190 hci_cc_read_voice_setting(hdev, skb);
2191 break;
2192
2193 case HCI_OP_WRITE_VOICE_SETTING:
2194 hci_cc_write_voice_setting(hdev, skb);
2195 break;
2196
2197 case HCI_OP_HOST_BUFFER_SIZE:
2198 hci_cc_host_buffer_size(hdev, skb);
2199 break;
2200
Marcel Holtmann333140b2008-07-14 20:13:48 +02002201 case HCI_OP_READ_SSP_MODE:
2202 hci_cc_read_ssp_mode(hdev, skb);
2203 break;
2204
2205 case HCI_OP_WRITE_SSP_MODE:
2206 hci_cc_write_ssp_mode(hdev, skb);
2207 break;
2208
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002209 case HCI_OP_READ_LOCAL_VERSION:
2210 hci_cc_read_local_version(hdev, skb);
2211 break;
2212
2213 case HCI_OP_READ_LOCAL_COMMANDS:
2214 hci_cc_read_local_commands(hdev, skb);
2215 break;
2216
2217 case HCI_OP_READ_LOCAL_FEATURES:
2218 hci_cc_read_local_features(hdev, skb);
2219 break;
2220
Andre Guedes971e3a42011-06-30 19:20:52 -03002221 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2222 hci_cc_read_local_ext_features(hdev, skb);
2223 break;
2224
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002225 case HCI_OP_READ_BUFFER_SIZE:
2226 hci_cc_read_buffer_size(hdev, skb);
2227 break;
2228
2229 case HCI_OP_READ_BD_ADDR:
2230 hci_cc_read_bd_addr(hdev, skb);
2231 break;
2232
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002233 case HCI_OP_READ_DATA_BLOCK_SIZE:
2234 hci_cc_read_data_block_size(hdev, skb);
2235 break;
2236
Johan Hedberg23bb5762010-12-21 23:01:27 +02002237 case HCI_OP_WRITE_CA_TIMEOUT:
2238 hci_cc_write_ca_timeout(hdev, skb);
2239 break;
2240
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002241 case HCI_OP_READ_FLOW_CONTROL_MODE:
2242 hci_cc_read_flow_control_mode(hdev, skb);
2243 break;
2244
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002245 case HCI_OP_READ_LOCAL_AMP_INFO:
2246 hci_cc_read_local_amp_info(hdev, skb);
2247 break;
2248
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002249 case HCI_OP_DELETE_STORED_LINK_KEY:
2250 hci_cc_delete_stored_link_key(hdev, skb);
2251 break;
2252
Johan Hedbergd5859e22011-01-25 01:19:58 +02002253 case HCI_OP_SET_EVENT_MASK:
2254 hci_cc_set_event_mask(hdev, skb);
2255 break;
2256
2257 case HCI_OP_WRITE_INQUIRY_MODE:
2258 hci_cc_write_inquiry_mode(hdev, skb);
2259 break;
2260
2261 case HCI_OP_READ_INQ_RSP_TX_POWER:
2262 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2263 break;
2264
2265 case HCI_OP_SET_EVENT_FLT:
2266 hci_cc_set_event_flt(hdev, skb);
2267 break;
2268
Johan Hedberg980e1a52011-01-22 06:10:07 +02002269 case HCI_OP_PIN_CODE_REPLY:
2270 hci_cc_pin_code_reply(hdev, skb);
2271 break;
2272
2273 case HCI_OP_PIN_CODE_NEG_REPLY:
2274 hci_cc_pin_code_neg_reply(hdev, skb);
2275 break;
2276
Szymon Jancc35938b2011-03-22 13:12:21 +01002277 case HCI_OP_READ_LOCAL_OOB_DATA:
2278 hci_cc_read_local_oob_data_reply(hdev, skb);
2279 break;
2280
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002281 case HCI_OP_LE_READ_BUFFER_SIZE:
2282 hci_cc_le_read_buffer_size(hdev, skb);
2283 break;
2284
Johan Hedberga5c29682011-02-19 12:05:57 -03002285 case HCI_OP_USER_CONFIRM_REPLY:
2286 hci_cc_user_confirm_reply(hdev, skb);
2287 break;
2288
2289 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2290 hci_cc_user_confirm_neg_reply(hdev, skb);
2291 break;
2292
Brian Gix1143d452011-11-23 08:28:34 -08002293 case HCI_OP_USER_PASSKEY_REPLY:
2294 hci_cc_user_passkey_reply(hdev, skb);
2295 break;
2296
2297 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2298 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002299
2300 case HCI_OP_LE_SET_SCAN_PARAM:
2301 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002302 break;
2303
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002304 case HCI_OP_LE_SET_SCAN_ENABLE:
2305 hci_cc_le_set_scan_enable(hdev, skb);
2306 break;
2307
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002308 case HCI_OP_LE_LTK_REPLY:
2309 hci_cc_le_ltk_reply(hdev, skb);
2310 break;
2311
2312 case HCI_OP_LE_LTK_NEG_REPLY:
2313 hci_cc_le_ltk_neg_reply(hdev, skb);
2314 break;
2315
Andre Guedesf9b49302011-06-30 19:20:53 -03002316 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2317 hci_cc_write_le_host_supported(hdev, skb);
2318 break;
2319
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002320 default:
2321 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2322 break;
2323 }
2324
Ville Tervo6bd32322011-02-16 16:32:41 +02002325 if (ev->opcode != HCI_OP_NOP)
2326 del_timer(&hdev->cmd_timer);
2327
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002328 if (ev->ncmd) {
2329 atomic_set(&hdev->cmd_cnt, 1);
2330 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002331 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002332 }
2333}
2334
2335static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2336{
2337 struct hci_ev_cmd_status *ev = (void *) skb->data;
2338 __u16 opcode;
2339
2340 skb_pull(skb, sizeof(*ev));
2341
2342 opcode = __le16_to_cpu(ev->opcode);
2343
2344 switch (opcode) {
2345 case HCI_OP_INQUIRY:
2346 hci_cs_inquiry(hdev, ev->status);
2347 break;
2348
2349 case HCI_OP_CREATE_CONN:
2350 hci_cs_create_conn(hdev, ev->status);
2351 break;
2352
2353 case HCI_OP_ADD_SCO:
2354 hci_cs_add_sco(hdev, ev->status);
2355 break;
2356
Marcel Holtmannf8558552008-07-14 20:13:49 +02002357 case HCI_OP_AUTH_REQUESTED:
2358 hci_cs_auth_requested(hdev, ev->status);
2359 break;
2360
2361 case HCI_OP_SET_CONN_ENCRYPT:
2362 hci_cs_set_conn_encrypt(hdev, ev->status);
2363 break;
2364
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002365 case HCI_OP_REMOTE_NAME_REQ:
2366 hci_cs_remote_name_req(hdev, ev->status);
2367 break;
2368
Marcel Holtmann769be972008-07-14 20:13:49 +02002369 case HCI_OP_READ_REMOTE_FEATURES:
2370 hci_cs_read_remote_features(hdev, ev->status);
2371 break;
2372
2373 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2374 hci_cs_read_remote_ext_features(hdev, ev->status);
2375 break;
2376
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002377 case HCI_OP_SETUP_SYNC_CONN:
2378 hci_cs_setup_sync_conn(hdev, ev->status);
2379 break;
2380
2381 case HCI_OP_SNIFF_MODE:
2382 hci_cs_sniff_mode(hdev, ev->status);
2383 break;
2384
2385 case HCI_OP_EXIT_SNIFF_MODE:
2386 hci_cs_exit_sniff_mode(hdev, ev->status);
2387 break;
2388
Johan Hedberg8962ee72011-01-20 12:40:27 +02002389 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002390 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002391 break;
2392
Ville Tervofcd89c02011-02-10 22:38:47 -03002393 case HCI_OP_LE_CREATE_CONN:
2394 hci_cs_le_create_conn(hdev, ev->status);
2395 break;
2396
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002397 case HCI_OP_LE_START_ENC:
2398 hci_cs_le_start_enc(hdev, ev->status);
2399 break;
2400
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002401 default:
2402 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2403 break;
2404 }
2405
Ville Tervo6bd32322011-02-16 16:32:41 +02002406 if (ev->opcode != HCI_OP_NOP)
2407 del_timer(&hdev->cmd_timer);
2408
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002409 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002410 atomic_set(&hdev->cmd_cnt, 1);
2411 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002412 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002413 }
2414}
2415
2416static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2417{
2418 struct hci_ev_role_change *ev = (void *) skb->data;
2419 struct hci_conn *conn;
2420
2421 BT_DBG("%s status %d", hdev->name, ev->status);
2422
2423 hci_dev_lock(hdev);
2424
2425 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2426 if (conn) {
2427 if (!ev->status) {
2428 if (ev->role)
2429 conn->link_mode &= ~HCI_LM_MASTER;
2430 else
2431 conn->link_mode |= HCI_LM_MASTER;
2432 }
2433
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002434 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002435
2436 hci_role_switch_cfm(conn, ev->status, ev->role);
2437 }
2438
2439 hci_dev_unlock(hdev);
2440}
2441
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2443{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002444 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002445 int i;
2446
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002447 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2448 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2449 return;
2450 }
2451
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002452 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2453 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002454 BT_DBG("%s bad parameters", hdev->name);
2455 return;
2456 }
2457
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002458 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2459
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002460 for (i = 0; i < ev->num_hndl; i++) {
2461 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002462 struct hci_conn *conn;
2463 __u16 handle, count;
2464
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002465 handle = __le16_to_cpu(info->handle);
2466 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002467
2468 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002469 if (!conn)
2470 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002471
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002472 conn->sent -= count;
2473
2474 switch (conn->type) {
2475 case ACL_LINK:
2476 hdev->acl_cnt += count;
2477 if (hdev->acl_cnt > hdev->acl_pkts)
2478 hdev->acl_cnt = hdev->acl_pkts;
2479 break;
2480
2481 case LE_LINK:
2482 if (hdev->le_pkts) {
2483 hdev->le_cnt += count;
2484 if (hdev->le_cnt > hdev->le_pkts)
2485 hdev->le_cnt = hdev->le_pkts;
2486 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002487 hdev->acl_cnt += count;
2488 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002489 hdev->acl_cnt = hdev->acl_pkts;
2490 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002491 break;
2492
2493 case SCO_LINK:
2494 hdev->sco_cnt += count;
2495 if (hdev->sco_cnt > hdev->sco_pkts)
2496 hdev->sco_cnt = hdev->sco_pkts;
2497 break;
2498
2499 default:
2500 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2501 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502 }
2503 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002504
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002505 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002506}
2507
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002508static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2509 struct sk_buff *skb)
2510{
2511 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2512 int i;
2513
2514 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2515 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2516 return;
2517 }
2518
2519 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2520 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2521 BT_DBG("%s bad parameters", hdev->name);
2522 return;
2523 }
2524
2525 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2526 ev->num_hndl);
2527
2528 for (i = 0; i < ev->num_hndl; i++) {
2529 struct hci_comp_blocks_info *info = &ev->handles[i];
2530 struct hci_conn *conn;
2531 __u16 handle, block_count;
2532
2533 handle = __le16_to_cpu(info->handle);
2534 block_count = __le16_to_cpu(info->blocks);
2535
2536 conn = hci_conn_hash_lookup_handle(hdev, handle);
2537 if (!conn)
2538 continue;
2539
2540 conn->sent -= block_count;
2541
2542 switch (conn->type) {
2543 case ACL_LINK:
2544 hdev->block_cnt += block_count;
2545 if (hdev->block_cnt > hdev->num_blocks)
2546 hdev->block_cnt = hdev->num_blocks;
2547 break;
2548
2549 default:
2550 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2551 break;
2552 }
2553 }
2554
2555 queue_work(hdev->workqueue, &hdev->tx_work);
2556}
2557
Marcel Holtmann04837f62006-07-03 10:02:33 +02002558static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002560 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002561 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562
2563 BT_DBG("%s status %d", hdev->name, ev->status);
2564
2565 hci_dev_lock(hdev);
2566
Marcel Holtmann04837f62006-07-03 10:02:33 +02002567 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2568 if (conn) {
2569 conn->mode = ev->mode;
2570 conn->interval = __le16_to_cpu(ev->interval);
2571
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002572 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002573 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002574 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002575 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002576 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002577 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002578
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002579 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002580 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002581 }
2582
2583 hci_dev_unlock(hdev);
2584}
2585
Linus Torvalds1da177e2005-04-16 15:20:36 -07002586static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2587{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002588 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2589 struct hci_conn *conn;
2590
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002591 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002592
2593 hci_dev_lock(hdev);
2594
2595 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002596 if (!conn)
2597 goto unlock;
2598
2599 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002600 hci_conn_hold(conn);
2601 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2602 hci_conn_put(conn);
2603 }
2604
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002605 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002606 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2607 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002608 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002609 u8 secure;
2610
2611 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2612 secure = 1;
2613 else
2614 secure = 0;
2615
Johan Hedberg744cf192011-11-08 20:40:14 +02002616 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002617 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002618
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002619unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002620 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002621}
2622
Linus Torvalds1da177e2005-04-16 15:20:36 -07002623static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2624{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002625 struct hci_ev_link_key_req *ev = (void *) skb->data;
2626 struct hci_cp_link_key_reply cp;
2627 struct hci_conn *conn;
2628 struct link_key *key;
2629
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002630 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002631
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002632 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002633 return;
2634
2635 hci_dev_lock(hdev);
2636
2637 key = hci_find_link_key(hdev, &ev->bdaddr);
2638 if (!key) {
2639 BT_DBG("%s link key not found for %s", hdev->name,
2640 batostr(&ev->bdaddr));
2641 goto not_found;
2642 }
2643
2644 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2645 batostr(&ev->bdaddr));
2646
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002647 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002648 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002649 BT_DBG("%s ignoring debug key", hdev->name);
2650 goto not_found;
2651 }
2652
2653 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002654 if (conn) {
2655 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2656 conn->auth_type != 0xff &&
2657 (conn->auth_type & 0x01)) {
2658 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2659 goto not_found;
2660 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002661
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002662 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2663 conn->pending_sec_level == BT_SECURITY_HIGH) {
2664 BT_DBG("%s ignoring key unauthenticated for high \
2665 security", hdev->name);
2666 goto not_found;
2667 }
2668
2669 conn->key_type = key->type;
2670 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002671 }
2672
2673 bacpy(&cp.bdaddr, &ev->bdaddr);
2674 memcpy(cp.link_key, key->val, 16);
2675
2676 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2677
2678 hci_dev_unlock(hdev);
2679
2680 return;
2681
2682not_found:
2683 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2684 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002685}
2686
Linus Torvalds1da177e2005-04-16 15:20:36 -07002687static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2688{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002689 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2690 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002691 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002692
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002693 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002694
2695 hci_dev_lock(hdev);
2696
2697 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2698 if (conn) {
2699 hci_conn_hold(conn);
2700 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002701 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002702
2703 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2704 conn->key_type = ev->key_type;
2705
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002706 hci_conn_put(conn);
2707 }
2708
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002709 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002710 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002711 ev->key_type, pin_len);
2712
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002713 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002714}
2715
Marcel Holtmann04837f62006-07-03 10:02:33 +02002716static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2717{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002718 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002719 struct hci_conn *conn;
2720
2721 BT_DBG("%s status %d", hdev->name, ev->status);
2722
2723 hci_dev_lock(hdev);
2724
2725 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002726 if (conn && !ev->status) {
2727 struct inquiry_entry *ie;
2728
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002729 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2730 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731 ie->data.clock_offset = ev->clock_offset;
2732 ie->timestamp = jiffies;
2733 }
2734 }
2735
2736 hci_dev_unlock(hdev);
2737}
2738
Marcel Holtmanna8746412008-07-14 20:13:46 +02002739static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2740{
2741 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2742 struct hci_conn *conn;
2743
2744 BT_DBG("%s status %d", hdev->name, ev->status);
2745
2746 hci_dev_lock(hdev);
2747
2748 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2749 if (conn && !ev->status)
2750 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2751
2752 hci_dev_unlock(hdev);
2753}
2754
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002755static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2756{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002757 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002758 struct inquiry_entry *ie;
2759
2760 BT_DBG("%s", hdev->name);
2761
2762 hci_dev_lock(hdev);
2763
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002764 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2765 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002766 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2767 ie->timestamp = jiffies;
2768 }
2769
2770 hci_dev_unlock(hdev);
2771}
2772
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002773static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2774{
2775 struct inquiry_data data;
2776 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg31754052012-01-04 13:39:52 +02002777 bool name_known;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002778
2779 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2780
2781 if (!num_rsp)
2782 return;
2783
2784 hci_dev_lock(hdev);
2785
2786 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002787 struct inquiry_info_with_rssi_and_pscan_mode *info;
2788 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002789
Johan Hedberge17acd42011-03-30 23:57:16 +03002790 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002791 bacpy(&data.bdaddr, &info->bdaddr);
2792 data.pscan_rep_mode = info->pscan_rep_mode;
2793 data.pscan_period_mode = info->pscan_period_mode;
2794 data.pscan_mode = info->pscan_mode;
2795 memcpy(data.dev_class, info->dev_class, 3);
2796 data.clock_offset = info->clock_offset;
2797 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002798 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002799
2800 name_known = hci_inquiry_cache_update(hdev, &data,
2801 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002802 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002803 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002804 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002805 }
2806 } else {
2807 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2808
Johan Hedberge17acd42011-03-30 23:57:16 +03002809 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002810 bacpy(&data.bdaddr, &info->bdaddr);
2811 data.pscan_rep_mode = info->pscan_rep_mode;
2812 data.pscan_period_mode = info->pscan_period_mode;
2813 data.pscan_mode = 0x00;
2814 memcpy(data.dev_class, info->dev_class, 3);
2815 data.clock_offset = info->clock_offset;
2816 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002817 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002818 name_known = hci_inquiry_cache_update(hdev, &data,
2819 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002820 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002821 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002822 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002823 }
2824 }
2825
2826 hci_dev_unlock(hdev);
2827}
2828
2829static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2830{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002831 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2832 struct hci_conn *conn;
2833
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002834 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002835
Marcel Holtmann41a96212008-07-14 20:13:48 +02002836 hci_dev_lock(hdev);
2837
2838 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002839 if (!conn)
2840 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002841
Johan Hedbergccd556f2010-11-10 17:11:51 +02002842 if (!ev->status && ev->page == 0x01) {
2843 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002844
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002845 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2846 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002847 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002848
Johan Hedberg58a681e2012-01-16 06:47:28 +02002849 if (ev->features[0] & 0x01)
2850 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002851 }
2852
Johan Hedbergccd556f2010-11-10 17:11:51 +02002853 if (conn->state != BT_CONFIG)
2854 goto unlock;
2855
Johan Hedberg127178d2010-11-18 22:22:29 +02002856 if (!ev->status) {
2857 struct hci_cp_remote_name_req cp;
2858 memset(&cp, 0, sizeof(cp));
2859 bacpy(&cp.bdaddr, &conn->dst);
2860 cp.pscan_rep_mode = 0x02;
2861 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002862 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2863 mgmt_device_connected(hdev, &conn->dst, conn->type,
2864 conn->dst_type, NULL, 0,
2865 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002866
Johan Hedberg127178d2010-11-18 22:22:29 +02002867 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002868 conn->state = BT_CONNECTED;
2869 hci_proto_connect_cfm(conn, ev->status);
2870 hci_conn_put(conn);
2871 }
2872
2873unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002874 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002875}
2876
2877static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2878{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002879 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2880 struct hci_conn *conn;
2881
2882 BT_DBG("%s status %d", hdev->name, ev->status);
2883
2884 hci_dev_lock(hdev);
2885
2886 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002887 if (!conn) {
2888 if (ev->link_type == ESCO_LINK)
2889 goto unlock;
2890
2891 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2892 if (!conn)
2893 goto unlock;
2894
2895 conn->type = SCO_LINK;
2896 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002897
Marcel Holtmann732547f2009-04-19 19:14:14 +02002898 switch (ev->status) {
2899 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002900 conn->handle = __le16_to_cpu(ev->handle);
2901 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002902
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002903 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002904 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002905 break;
2906
Stephen Coe705e5712010-02-16 11:29:44 -05002907 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002908 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002909 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002910 case 0x1f: /* Unspecified error */
2911 if (conn->out && conn->attempt < 2) {
2912 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2913 (hdev->esco_type & EDR_ESCO_MASK);
2914 hci_setup_sync(conn, conn->link->handle);
2915 goto unlock;
2916 }
2917 /* fall through */
2918
2919 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002920 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002921 break;
2922 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002923
2924 hci_proto_connect_cfm(conn, ev->status);
2925 if (ev->status)
2926 hci_conn_del(conn);
2927
2928unlock:
2929 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002930}
2931
2932static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2933{
2934 BT_DBG("%s", hdev->name);
2935}
2936
Marcel Holtmann04837f62006-07-03 10:02:33 +02002937static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2938{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002939 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002940
2941 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002942}
2943
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002944static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2945{
2946 struct inquiry_data data;
2947 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2948 int num_rsp = *((__u8 *) skb->data);
2949
2950 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2951
2952 if (!num_rsp)
2953 return;
2954
2955 hci_dev_lock(hdev);
2956
Johan Hedberge17acd42011-03-30 23:57:16 +03002957 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg561aafb2012-01-04 13:31:59 +02002958 bool name_known;
2959
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002960 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002961 data.pscan_rep_mode = info->pscan_rep_mode;
2962 data.pscan_period_mode = info->pscan_period_mode;
2963 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002964 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002965 data.clock_offset = info->clock_offset;
2966 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002967 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002968
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002969 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002970 name_known = eir_has_data_type(info->data,
2971 sizeof(info->data),
2972 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002973 else
2974 name_known = true;
2975
Johan Hedberg31754052012-01-04 13:39:52 +02002976 name_known = hci_inquiry_cache_update(hdev, &data, name_known);
Johan Hedberg48264f02011-11-09 13:58:58 +02002977 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002978 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002979 !name_known, info->data,
2980 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002981 }
2982
2983 hci_dev_unlock(hdev);
2984}
2985
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002986static inline u8 hci_get_auth_req(struct hci_conn *conn)
2987{
2988 /* If remote requests dedicated bonding follow that lead */
2989 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2990 /* If both remote and local IO capabilities allow MITM
2991 * protection then require it, otherwise don't */
2992 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2993 return 0x02;
2994 else
2995 return 0x03;
2996 }
2997
2998 /* If remote requests no-bonding follow that lead */
2999 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003000 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003001
3002 return conn->auth_type;
3003}
3004
Marcel Holtmann04936842008-07-14 20:13:48 +02003005static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3006{
3007 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3008 struct hci_conn *conn;
3009
3010 BT_DBG("%s", hdev->name);
3011
3012 hci_dev_lock(hdev);
3013
3014 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003015 if (!conn)
3016 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003017
Johan Hedberg03b555e2011-01-04 15:40:05 +02003018 hci_conn_hold(conn);
3019
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003020 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003021 goto unlock;
3022
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003023 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003024 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003025 struct hci_cp_io_capability_reply cp;
3026
3027 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303028 /* Change the IO capability from KeyboardDisplay
3029 * to DisplayYesNo as it is not supported by BT spec. */
3030 cp.capability = (conn->io_capability == 0x04) ?
3031 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003032 conn->auth_type = hci_get_auth_req(conn);
3033 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003034
Johan Hedberg58a681e2012-01-16 06:47:28 +02003035 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003036 hci_find_remote_oob_data(hdev, &conn->dst))
3037 cp.oob_data = 0x01;
3038 else
3039 cp.oob_data = 0x00;
3040
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003041 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3042 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003043 } else {
3044 struct hci_cp_io_capability_neg_reply cp;
3045
3046 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003047 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003048
3049 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3050 sizeof(cp), &cp);
3051 }
3052
3053unlock:
3054 hci_dev_unlock(hdev);
3055}
3056
3057static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3058{
3059 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3060 struct hci_conn *conn;
3061
3062 BT_DBG("%s", hdev->name);
3063
3064 hci_dev_lock(hdev);
3065
3066 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3067 if (!conn)
3068 goto unlock;
3069
Johan Hedberg03b555e2011-01-04 15:40:05 +02003070 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003071 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003072 if (ev->oob_data)
3073 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003074
3075unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003076 hci_dev_unlock(hdev);
3077}
3078
Johan Hedberga5c29682011-02-19 12:05:57 -03003079static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3080 struct sk_buff *skb)
3081{
3082 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003083 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003084 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003085
3086 BT_DBG("%s", hdev->name);
3087
3088 hci_dev_lock(hdev);
3089
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003090 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003091 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003092
Johan Hedberg7a828902011-04-28 11:28:53 -07003093 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3094 if (!conn)
3095 goto unlock;
3096
3097 loc_mitm = (conn->auth_type & 0x01);
3098 rem_mitm = (conn->remote_auth & 0x01);
3099
3100 /* If we require MITM but the remote device can't provide that
3101 * (it has NoInputNoOutput) then reject the confirmation
3102 * request. The only exception is when we're dedicated bonding
3103 * initiators (connect_cfm_cb set) since then we always have the MITM
3104 * bit set. */
3105 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3106 BT_DBG("Rejecting request: remote device can't provide MITM");
3107 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3108 sizeof(ev->bdaddr), &ev->bdaddr);
3109 goto unlock;
3110 }
3111
3112 /* If no side requires MITM protection; auto-accept */
3113 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3114 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003115
3116 /* If we're not the initiators request authorization to
3117 * proceed from user space (mgmt_user_confirm with
3118 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003119 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003120 BT_DBG("Confirming auto-accept as acceptor");
3121 confirm_hint = 1;
3122 goto confirm;
3123 }
3124
Johan Hedberg9f616562011-04-28 11:28:54 -07003125 BT_DBG("Auto-accept of user confirmation with %ums delay",
3126 hdev->auto_accept_delay);
3127
3128 if (hdev->auto_accept_delay > 0) {
3129 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3130 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3131 goto unlock;
3132 }
3133
Johan Hedberg7a828902011-04-28 11:28:53 -07003134 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3135 sizeof(ev->bdaddr), &ev->bdaddr);
3136 goto unlock;
3137 }
3138
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003139confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003140 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003141 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003142
3143unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003144 hci_dev_unlock(hdev);
3145}
3146
Brian Gix1143d452011-11-23 08:28:34 -08003147static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3148 struct sk_buff *skb)
3149{
3150 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3151
3152 BT_DBG("%s", hdev->name);
3153
3154 hci_dev_lock(hdev);
3155
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003156 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003157 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003158
3159 hci_dev_unlock(hdev);
3160}
3161
Marcel Holtmann04936842008-07-14 20:13:48 +02003162static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3163{
3164 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3165 struct hci_conn *conn;
3166
3167 BT_DBG("%s", hdev->name);
3168
3169 hci_dev_lock(hdev);
3170
3171 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003172 if (!conn)
3173 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003174
Johan Hedberg2a611692011-02-19 12:06:00 -03003175 /* To avoid duplicate auth_failed events to user space we check
3176 * the HCI_CONN_AUTH_PEND flag which will be set if we
3177 * initiated the authentication. A traditional auth_complete
3178 * event gets always produced as initiator and is also mapped to
3179 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003180 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003181 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3182 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003183
3184 hci_conn_put(conn);
3185
3186unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003187 hci_dev_unlock(hdev);
3188}
3189
Marcel Holtmann41a96212008-07-14 20:13:48 +02003190static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3191{
3192 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3193 struct inquiry_entry *ie;
3194
3195 BT_DBG("%s", hdev->name);
3196
3197 hci_dev_lock(hdev);
3198
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003199 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3200 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003201 ie->data.ssp_mode = (ev->features[0] & 0x01);
3202
3203 hci_dev_unlock(hdev);
3204}
3205
Szymon Janc2763eda2011-03-22 13:12:22 +01003206static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3207 struct sk_buff *skb)
3208{
3209 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3210 struct oob_data *data;
3211
3212 BT_DBG("%s", hdev->name);
3213
3214 hci_dev_lock(hdev);
3215
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003216 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003217 goto unlock;
3218
Szymon Janc2763eda2011-03-22 13:12:22 +01003219 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3220 if (data) {
3221 struct hci_cp_remote_oob_data_reply cp;
3222
3223 bacpy(&cp.bdaddr, &ev->bdaddr);
3224 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3225 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3226
3227 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3228 &cp);
3229 } else {
3230 struct hci_cp_remote_oob_data_neg_reply cp;
3231
3232 bacpy(&cp.bdaddr, &ev->bdaddr);
3233 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3234 &cp);
3235 }
3236
Szymon Jance1ba1f12011-04-06 13:01:59 +02003237unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003238 hci_dev_unlock(hdev);
3239}
3240
Ville Tervofcd89c02011-02-10 22:38:47 -03003241static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3242{
3243 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3244 struct hci_conn *conn;
3245
3246 BT_DBG("%s status %d", hdev->name, ev->status);
3247
3248 hci_dev_lock(hdev);
3249
3250 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003251 if (!conn) {
3252 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3253 if (!conn) {
3254 BT_ERR("No memory for new connection");
3255 hci_dev_unlock(hdev);
3256 return;
3257 }
Andre Guedes29b79882011-05-31 14:20:54 -03003258
3259 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003260 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003261
3262 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003263 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3264 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003265 hci_proto_connect_cfm(conn, ev->status);
3266 conn->state = BT_CLOSED;
3267 hci_conn_del(conn);
3268 goto unlock;
3269 }
3270
Johan Hedbergb644ba32012-01-17 21:48:47 +02003271 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3272 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3273 conn->dst_type, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003274
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003275 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003276 conn->handle = __le16_to_cpu(ev->handle);
3277 conn->state = BT_CONNECTED;
3278
3279 hci_conn_hold_device(conn);
3280 hci_conn_add_sysfs(conn);
3281
3282 hci_proto_connect_cfm(conn, ev->status);
3283
3284unlock:
3285 hci_dev_unlock(hdev);
3286}
3287
Andre Guedes9aa04c92011-05-26 16:23:51 -03003288static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3289 struct sk_buff *skb)
3290{
Andre Guedese95beb42011-09-26 20:48:35 -03003291 u8 num_reports = skb->data[0];
3292 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003293 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003294
3295 hci_dev_lock(hdev);
3296
Andre Guedese95beb42011-09-26 20:48:35 -03003297 while (num_reports--) {
3298 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003299
Andre Guedes9aa04c92011-05-26 16:23:51 -03003300 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003301
Andre Guedes3c9e9192012-01-10 18:20:50 -03003302 rssi = ev->data[ev->length];
3303 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3304 NULL, rssi, 0, ev->data, ev->length);
3305
Andre Guedese95beb42011-09-26 20:48:35 -03003306 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003307 }
3308
3309 hci_dev_unlock(hdev);
3310}
3311
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003312static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3313 struct sk_buff *skb)
3314{
3315 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3316 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003317 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003318 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003319 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003320
3321 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3322
3323 hci_dev_lock(hdev);
3324
3325 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003326 if (conn == NULL)
3327 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003328
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003329 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3330 if (ltk == NULL)
3331 goto not_found;
3332
3333 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003334 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003335
3336 if (ltk->authenticated)
3337 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003338
3339 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3340
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003341 if (ltk->type & HCI_SMP_STK) {
3342 list_del(&ltk->list);
3343 kfree(ltk);
3344 }
3345
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003346 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003347
3348 return;
3349
3350not_found:
3351 neg.handle = ev->handle;
3352 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3353 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003354}
3355
Ville Tervofcd89c02011-02-10 22:38:47 -03003356static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3357{
3358 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3359
3360 skb_pull(skb, sizeof(*le_ev));
3361
3362 switch (le_ev->subevent) {
3363 case HCI_EV_LE_CONN_COMPLETE:
3364 hci_le_conn_complete_evt(hdev, skb);
3365 break;
3366
Andre Guedes9aa04c92011-05-26 16:23:51 -03003367 case HCI_EV_LE_ADVERTISING_REPORT:
3368 hci_le_adv_report_evt(hdev, skb);
3369 break;
3370
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003371 case HCI_EV_LE_LTK_REQ:
3372 hci_le_ltk_request_evt(hdev, skb);
3373 break;
3374
Ville Tervofcd89c02011-02-10 22:38:47 -03003375 default:
3376 break;
3377 }
3378}
3379
Linus Torvalds1da177e2005-04-16 15:20:36 -07003380void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3381{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003382 struct hci_event_hdr *hdr = (void *) skb->data;
3383 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003384
3385 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3386
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003387 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003388 case HCI_EV_INQUIRY_COMPLETE:
3389 hci_inquiry_complete_evt(hdev, skb);
3390 break;
3391
3392 case HCI_EV_INQUIRY_RESULT:
3393 hci_inquiry_result_evt(hdev, skb);
3394 break;
3395
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003396 case HCI_EV_CONN_COMPLETE:
3397 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003398 break;
3399
Linus Torvalds1da177e2005-04-16 15:20:36 -07003400 case HCI_EV_CONN_REQUEST:
3401 hci_conn_request_evt(hdev, skb);
3402 break;
3403
Linus Torvalds1da177e2005-04-16 15:20:36 -07003404 case HCI_EV_DISCONN_COMPLETE:
3405 hci_disconn_complete_evt(hdev, skb);
3406 break;
3407
Linus Torvalds1da177e2005-04-16 15:20:36 -07003408 case HCI_EV_AUTH_COMPLETE:
3409 hci_auth_complete_evt(hdev, skb);
3410 break;
3411
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003412 case HCI_EV_REMOTE_NAME:
3413 hci_remote_name_evt(hdev, skb);
3414 break;
3415
Linus Torvalds1da177e2005-04-16 15:20:36 -07003416 case HCI_EV_ENCRYPT_CHANGE:
3417 hci_encrypt_change_evt(hdev, skb);
3418 break;
3419
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003420 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3421 hci_change_link_key_complete_evt(hdev, skb);
3422 break;
3423
3424 case HCI_EV_REMOTE_FEATURES:
3425 hci_remote_features_evt(hdev, skb);
3426 break;
3427
3428 case HCI_EV_REMOTE_VERSION:
3429 hci_remote_version_evt(hdev, skb);
3430 break;
3431
3432 case HCI_EV_QOS_SETUP_COMPLETE:
3433 hci_qos_setup_complete_evt(hdev, skb);
3434 break;
3435
3436 case HCI_EV_CMD_COMPLETE:
3437 hci_cmd_complete_evt(hdev, skb);
3438 break;
3439
3440 case HCI_EV_CMD_STATUS:
3441 hci_cmd_status_evt(hdev, skb);
3442 break;
3443
3444 case HCI_EV_ROLE_CHANGE:
3445 hci_role_change_evt(hdev, skb);
3446 break;
3447
3448 case HCI_EV_NUM_COMP_PKTS:
3449 hci_num_comp_pkts_evt(hdev, skb);
3450 break;
3451
3452 case HCI_EV_MODE_CHANGE:
3453 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003454 break;
3455
3456 case HCI_EV_PIN_CODE_REQ:
3457 hci_pin_code_request_evt(hdev, skb);
3458 break;
3459
3460 case HCI_EV_LINK_KEY_REQ:
3461 hci_link_key_request_evt(hdev, skb);
3462 break;
3463
3464 case HCI_EV_LINK_KEY_NOTIFY:
3465 hci_link_key_notify_evt(hdev, skb);
3466 break;
3467
3468 case HCI_EV_CLOCK_OFFSET:
3469 hci_clock_offset_evt(hdev, skb);
3470 break;
3471
Marcel Holtmanna8746412008-07-14 20:13:46 +02003472 case HCI_EV_PKT_TYPE_CHANGE:
3473 hci_pkt_type_change_evt(hdev, skb);
3474 break;
3475
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003476 case HCI_EV_PSCAN_REP_MODE:
3477 hci_pscan_rep_mode_evt(hdev, skb);
3478 break;
3479
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003480 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3481 hci_inquiry_result_with_rssi_evt(hdev, skb);
3482 break;
3483
3484 case HCI_EV_REMOTE_EXT_FEATURES:
3485 hci_remote_ext_features_evt(hdev, skb);
3486 break;
3487
3488 case HCI_EV_SYNC_CONN_COMPLETE:
3489 hci_sync_conn_complete_evt(hdev, skb);
3490 break;
3491
3492 case HCI_EV_SYNC_CONN_CHANGED:
3493 hci_sync_conn_changed_evt(hdev, skb);
3494 break;
3495
Marcel Holtmann04837f62006-07-03 10:02:33 +02003496 case HCI_EV_SNIFF_SUBRATE:
3497 hci_sniff_subrate_evt(hdev, skb);
3498 break;
3499
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003500 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3501 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003502 break;
3503
Marcel Holtmann04936842008-07-14 20:13:48 +02003504 case HCI_EV_IO_CAPA_REQUEST:
3505 hci_io_capa_request_evt(hdev, skb);
3506 break;
3507
Johan Hedberg03b555e2011-01-04 15:40:05 +02003508 case HCI_EV_IO_CAPA_REPLY:
3509 hci_io_capa_reply_evt(hdev, skb);
3510 break;
3511
Johan Hedberga5c29682011-02-19 12:05:57 -03003512 case HCI_EV_USER_CONFIRM_REQUEST:
3513 hci_user_confirm_request_evt(hdev, skb);
3514 break;
3515
Brian Gix1143d452011-11-23 08:28:34 -08003516 case HCI_EV_USER_PASSKEY_REQUEST:
3517 hci_user_passkey_request_evt(hdev, skb);
3518 break;
3519
Marcel Holtmann04936842008-07-14 20:13:48 +02003520 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3521 hci_simple_pair_complete_evt(hdev, skb);
3522 break;
3523
Marcel Holtmann41a96212008-07-14 20:13:48 +02003524 case HCI_EV_REMOTE_HOST_FEATURES:
3525 hci_remote_host_features_evt(hdev, skb);
3526 break;
3527
Ville Tervofcd89c02011-02-10 22:38:47 -03003528 case HCI_EV_LE_META:
3529 hci_le_meta_evt(hdev, skb);
3530 break;
3531
Szymon Janc2763eda2011-03-22 13:12:22 +01003532 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3533 hci_remote_oob_data_request_evt(hdev, skb);
3534 break;
3535
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003536 case HCI_EV_NUM_COMP_BLOCKS:
3537 hci_num_comp_blocks_evt(hdev, skb);
3538 break;
3539
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003540 default:
3541 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003542 break;
3543 }
3544
3545 kfree_skb(skb);
3546 hdev->stat.evt_rx++;
3547}
3548
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003549module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003550MODULE_PARM_DESC(enable_le, "Enable LE support");