blob: 93ecb2dfa1773f9c814a3c7cb835dde48cb64eb4 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
38#include <linux/notifier.h>
39#include <net/sock.h>
40
41#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020042#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <asm/unaligned.h>
44
45#include <net/bluetooth/bluetooth.h>
46#include <net/bluetooth/hci_core.h>
47
Andre Guedese6100a22011-06-30 19:20:54 -030048static int enable_le;
49
Linus Torvalds1da177e2005-04-16 15:20:36 -070050/* Handle HCI Event packets */
51
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070053{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020054 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Marcel Holtmanna9de9242007-10-20 13:33:56 +020056 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Andre Guedese6d465c2011-11-09 17:14:26 -030058 if (status) {
59 hci_dev_lock(hdev);
60 mgmt_stop_discovery_failed(hdev, status);
61 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020062 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030063 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Andre Guedes89352e72011-11-04 14:16:53 -030065 clear_bit(HCI_INQUIRY, &hdev->flags);
66
Johan Hedberg56e5cb82011-11-08 20:40:16 +020067 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +020068 mgmt_discovering(hdev, 0);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020069 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010070
Johan Hedberg23bb5762010-12-21 23:01:27 +020071 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010072
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070074}
75
Marcel Holtmanna9de9242007-10-20 13:33:56 +020076static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070077{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020078 __u8 status = *((__u8 *) skb->data);
79
80 BT_DBG("%s status 0x%x", hdev->name, status);
81
82 if (status)
83 return;
84
Marcel Holtmanna9de9242007-10-20 13:33:56 +020085 hci_conn_check_pending(hdev);
86}
87
88static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
89{
90 BT_DBG("%s", hdev->name);
91}
92
93static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
94{
95 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Marcel Holtmanna9de9242007-10-20 13:33:56 +020098 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 if (rp->status)
101 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200103 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
106 if (conn) {
107 if (rp->role)
108 conn->link_mode &= ~HCI_LM_MASTER;
109 else
110 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200112
113 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114}
115
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200116static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
117{
118 struct hci_rp_read_link_policy *rp = (void *) skb->data;
119 struct hci_conn *conn;
120
121 BT_DBG("%s status 0x%x", hdev->name, rp->status);
122
123 if (rp->status)
124 return;
125
126 hci_dev_lock(hdev);
127
128 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
129 if (conn)
130 conn->link_policy = __le16_to_cpu(rp->policy);
131
132 hci_dev_unlock(hdev);
133}
134
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200137 struct hci_rp_write_link_policy *rp = (void *) skb->data;
138 struct hci_conn *conn;
139 void *sent;
140
141 BT_DBG("%s status 0x%x", hdev->name, rp->status);
142
143 if (rp->status)
144 return;
145
146 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
147 if (!sent)
148 return;
149
150 hci_dev_lock(hdev);
151
152 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200153 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700154 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200155
156 hci_dev_unlock(hdev);
157}
158
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200159static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
160{
161 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
162
163 BT_DBG("%s status 0x%x", hdev->name, rp->status);
164
165 if (rp->status)
166 return;
167
168 hdev->link_policy = __le16_to_cpu(rp->policy);
169}
170
171static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
172{
173 __u8 status = *((__u8 *) skb->data);
174 void *sent;
175
176 BT_DBG("%s status 0x%x", hdev->name, status);
177
178 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
179 if (!sent)
180 return;
181
182 if (!status)
183 hdev->link_policy = get_unaligned_le16(sent);
184
Johan Hedberg23bb5762010-12-21 23:01:27 +0200185 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200186}
187
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200188static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
189{
190 __u8 status = *((__u8 *) skb->data);
191
192 BT_DBG("%s status 0x%x", hdev->name, status);
193
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300194 clear_bit(HCI_RESET, &hdev->flags);
195
Johan Hedberg23bb5762010-12-21 23:01:27 +0200196 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300197
198 hdev->dev_flags = 0;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200199}
200
201static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
202{
203 __u8 status = *((__u8 *) skb->data);
204 void *sent;
205
206 BT_DBG("%s status 0x%x", hdev->name, status);
207
208 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
209 if (!sent)
210 return;
211
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200212 hci_dev_lock(hdev);
213
Johan Hedbergb312b1612011-03-16 14:29:37 +0200214 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200215 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200216
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200217 if (status == 0)
218 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200219
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200220 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200221}
222
223static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
224{
225 struct hci_rp_read_local_name *rp = (void *) skb->data;
226
227 BT_DBG("%s status 0x%x", hdev->name, rp->status);
228
229 if (rp->status)
230 return;
231
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200232 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200233}
234
235static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
236{
237 __u8 status = *((__u8 *) skb->data);
238 void *sent;
239
240 BT_DBG("%s status 0x%x", hdev->name, status);
241
242 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
243 if (!sent)
244 return;
245
246 if (!status) {
247 __u8 param = *((__u8 *) sent);
248
249 if (param == AUTH_ENABLED)
250 set_bit(HCI_AUTH, &hdev->flags);
251 else
252 clear_bit(HCI_AUTH, &hdev->flags);
253 }
254
Johan Hedberg23bb5762010-12-21 23:01:27 +0200255 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200256}
257
258static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
259{
260 __u8 status = *((__u8 *) skb->data);
261 void *sent;
262
263 BT_DBG("%s status 0x%x", hdev->name, status);
264
265 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
266 if (!sent)
267 return;
268
269 if (!status) {
270 __u8 param = *((__u8 *) sent);
271
272 if (param)
273 set_bit(HCI_ENCRYPT, &hdev->flags);
274 else
275 clear_bit(HCI_ENCRYPT, &hdev->flags);
276 }
277
Johan Hedberg23bb5762010-12-21 23:01:27 +0200278 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200279}
280
281static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
282{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200283 __u8 param, status = *((__u8 *) skb->data);
284 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200285 void *sent;
286
287 BT_DBG("%s status 0x%x", hdev->name, status);
288
289 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
290 if (!sent)
291 return;
292
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200293 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200294
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200295 hci_dev_lock(hdev);
296
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200297 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200298 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200299 hdev->discov_timeout = 0;
300 goto done;
301 }
302
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200303 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
304 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200305
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200306 if (param & SCAN_INQUIRY) {
307 set_bit(HCI_ISCAN, &hdev->flags);
308 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200309 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200310 if (hdev->discov_timeout > 0) {
311 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
312 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
313 to);
314 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200315 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200316 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200317
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200318 if (param & SCAN_PAGE) {
319 set_bit(HCI_PSCAN, &hdev->flags);
320 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200321 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200322 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200323 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200324
325done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200326 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200327 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200328}
329
330static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
331{
332 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
333
334 BT_DBG("%s status 0x%x", hdev->name, rp->status);
335
336 if (rp->status)
337 return;
338
339 memcpy(hdev->dev_class, rp->dev_class, 3);
340
341 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
342 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
343}
344
345static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
346{
347 __u8 status = *((__u8 *) skb->data);
348 void *sent;
349
350 BT_DBG("%s status 0x%x", hdev->name, status);
351
Marcel Holtmannf383f272008-07-14 20:13:47 +0200352 if (status)
353 return;
354
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200355 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
356 if (!sent)
357 return;
358
Marcel Holtmannf383f272008-07-14 20:13:47 +0200359 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200360}
361
362static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
363{
364 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200366
367 BT_DBG("%s status 0x%x", hdev->name, rp->status);
368
369 if (rp->status)
370 return;
371
372 setting = __le16_to_cpu(rp->voice_setting);
373
Marcel Holtmannf383f272008-07-14 20:13:47 +0200374 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375 return;
376
377 hdev->voice_setting = setting;
378
379 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
380
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200381 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200382 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200383}
384
385static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
386{
387 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200388 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 void *sent;
390
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200391 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392
Marcel Holtmannf383f272008-07-14 20:13:47 +0200393 if (status)
394 return;
395
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200396 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
397 if (!sent)
398 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399
Marcel Holtmannf383f272008-07-14 20:13:47 +0200400 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401
Marcel Holtmannf383f272008-07-14 20:13:47 +0200402 if (hdev->voice_setting == setting)
403 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404
Marcel Holtmannf383f272008-07-14 20:13:47 +0200405 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
Marcel Holtmannf383f272008-07-14 20:13:47 +0200407 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
408
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200409 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411}
412
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200413static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200415 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200417 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
Johan Hedberg23bb5762010-12-21 23:01:27 +0200419 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420}
421
Marcel Holtmann333140b2008-07-14 20:13:48 +0200422static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
423{
424 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
425
426 BT_DBG("%s status 0x%x", hdev->name, rp->status);
427
428 if (rp->status)
429 return;
430
431 hdev->ssp_mode = rp->mode;
432}
433
434static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
435{
436 __u8 status = *((__u8 *) skb->data);
437 void *sent;
438
439 BT_DBG("%s status 0x%x", hdev->name, status);
440
441 if (status)
442 return;
443
444 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
445 if (!sent)
446 return;
447
448 hdev->ssp_mode = *((__u8 *) sent);
449}
450
Johan Hedbergd5859e22011-01-25 01:19:58 +0200451static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
452{
453 if (hdev->features[6] & LMP_EXT_INQ)
454 return 2;
455
456 if (hdev->features[3] & LMP_RSSI_INQ)
457 return 1;
458
459 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
460 hdev->lmp_subver == 0x0757)
461 return 1;
462
463 if (hdev->manufacturer == 15) {
464 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
465 return 1;
466 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
467 return 1;
468 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
469 return 1;
470 }
471
472 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
473 hdev->lmp_subver == 0x1805)
474 return 1;
475
476 return 0;
477}
478
479static void hci_setup_inquiry_mode(struct hci_dev *hdev)
480{
481 u8 mode;
482
483 mode = hci_get_inquiry_mode(hdev);
484
485 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
486}
487
488static void hci_setup_event_mask(struct hci_dev *hdev)
489{
490 /* The second byte is 0xff instead of 0x9f (two reserved bits
491 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
492 * command otherwise */
493 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
494
Ville Tervo6de6c182011-05-27 11:16:21 +0300495 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
496 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200497 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300498 return;
499
500 events[4] |= 0x01; /* Flow Specification Complete */
501 events[4] |= 0x02; /* Inquiry Result with RSSI */
502 events[4] |= 0x04; /* Read Remote Extended Features Complete */
503 events[5] |= 0x08; /* Synchronous Connection Complete */
504 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200505
506 if (hdev->features[3] & LMP_RSSI_INQ)
507 events[4] |= 0x04; /* Inquiry Result with RSSI */
508
509 if (hdev->features[5] & LMP_SNIFF_SUBR)
510 events[5] |= 0x20; /* Sniff Subrating */
511
512 if (hdev->features[5] & LMP_PAUSE_ENC)
513 events[5] |= 0x80; /* Encryption Key Refresh Complete */
514
515 if (hdev->features[6] & LMP_EXT_INQ)
516 events[5] |= 0x40; /* Extended Inquiry Result */
517
518 if (hdev->features[6] & LMP_NO_FLUSH)
519 events[7] |= 0x01; /* Enhanced Flush Complete */
520
521 if (hdev->features[7] & LMP_LSTO)
522 events[6] |= 0x80; /* Link Supervision Timeout Changed */
523
524 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
525 events[6] |= 0x01; /* IO Capability Request */
526 events[6] |= 0x02; /* IO Capability Response */
527 events[6] |= 0x04; /* User Confirmation Request */
528 events[6] |= 0x08; /* User Passkey Request */
529 events[6] |= 0x10; /* Remote OOB Data Request */
530 events[6] |= 0x20; /* Simple Pairing Complete */
531 events[7] |= 0x04; /* User Passkey Notification */
532 events[7] |= 0x08; /* Keypress Notification */
533 events[7] |= 0x10; /* Remote Host Supported
534 * Features Notification */
535 }
536
537 if (hdev->features[4] & LMP_LE)
538 events[7] |= 0x20; /* LE Meta-Event */
539
540 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
541}
542
Andre Guedese6100a22011-06-30 19:20:54 -0300543static void hci_set_le_support(struct hci_dev *hdev)
544{
545 struct hci_cp_write_le_host_supported cp;
546
547 memset(&cp, 0, sizeof(cp));
548
549 if (enable_le) {
550 cp.le = 1;
551 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
552 }
553
554 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
555}
556
Johan Hedbergd5859e22011-01-25 01:19:58 +0200557static void hci_setup(struct hci_dev *hdev)
558{
559 hci_setup_event_mask(hdev);
560
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200561 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200562 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
563
564 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
565 u8 mode = 0x01;
566 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
567 }
568
569 if (hdev->features[3] & LMP_RSSI_INQ)
570 hci_setup_inquiry_mode(hdev);
571
572 if (hdev->features[7] & LMP_INQ_TX_PWR)
573 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300574
575 if (hdev->features[7] & LMP_EXTFEATURES) {
576 struct hci_cp_read_local_ext_features cp;
577
578 cp.page = 0x01;
579 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
580 sizeof(cp), &cp);
581 }
Andre Guedese6100a22011-06-30 19:20:54 -0300582
583 if (hdev->features[4] & LMP_LE)
584 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200585}
586
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200587static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
588{
589 struct hci_rp_read_local_version *rp = (void *) skb->data;
590
591 BT_DBG("%s status 0x%x", hdev->name, rp->status);
592
593 if (rp->status)
594 return;
595
596 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200597 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200598 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200599 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200600 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200601
602 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
603 hdev->manufacturer,
604 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200605
606 if (test_bit(HCI_INIT, &hdev->flags))
607 hci_setup(hdev);
608}
609
610static void hci_setup_link_policy(struct hci_dev *hdev)
611{
612 u16 link_policy = 0;
613
614 if (hdev->features[0] & LMP_RSWITCH)
615 link_policy |= HCI_LP_RSWITCH;
616 if (hdev->features[0] & LMP_HOLD)
617 link_policy |= HCI_LP_HOLD;
618 if (hdev->features[0] & LMP_SNIFF)
619 link_policy |= HCI_LP_SNIFF;
620 if (hdev->features[1] & LMP_PARK)
621 link_policy |= HCI_LP_PARK;
622
623 link_policy = cpu_to_le16(link_policy);
624 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
625 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200626}
627
628static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
629{
630 struct hci_rp_read_local_commands *rp = (void *) skb->data;
631
632 BT_DBG("%s status 0x%x", hdev->name, rp->status);
633
634 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200635 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200636
637 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200638
639 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
640 hci_setup_link_policy(hdev);
641
642done:
643 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200644}
645
646static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
647{
648 struct hci_rp_read_local_features *rp = (void *) skb->data;
649
650 BT_DBG("%s status 0x%x", hdev->name, rp->status);
651
652 if (rp->status)
653 return;
654
655 memcpy(hdev->features, rp->features, 8);
656
657 /* Adjust default settings according to features
658 * supported by device. */
659
660 if (hdev->features[0] & LMP_3SLOT)
661 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
662
663 if (hdev->features[0] & LMP_5SLOT)
664 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
665
666 if (hdev->features[1] & LMP_HV2) {
667 hdev->pkt_type |= (HCI_HV2);
668 hdev->esco_type |= (ESCO_HV2);
669 }
670
671 if (hdev->features[1] & LMP_HV3) {
672 hdev->pkt_type |= (HCI_HV3);
673 hdev->esco_type |= (ESCO_HV3);
674 }
675
676 if (hdev->features[3] & LMP_ESCO)
677 hdev->esco_type |= (ESCO_EV3);
678
679 if (hdev->features[4] & LMP_EV4)
680 hdev->esco_type |= (ESCO_EV4);
681
682 if (hdev->features[4] & LMP_EV5)
683 hdev->esco_type |= (ESCO_EV5);
684
Marcel Holtmannefc76882009-02-06 09:13:37 +0100685 if (hdev->features[5] & LMP_EDR_ESCO_2M)
686 hdev->esco_type |= (ESCO_2EV3);
687
688 if (hdev->features[5] & LMP_EDR_ESCO_3M)
689 hdev->esco_type |= (ESCO_3EV3);
690
691 if (hdev->features[5] & LMP_EDR_3S_ESCO)
692 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
693
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200694 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
695 hdev->features[0], hdev->features[1],
696 hdev->features[2], hdev->features[3],
697 hdev->features[4], hdev->features[5],
698 hdev->features[6], hdev->features[7]);
699}
700
Andre Guedes971e3a42011-06-30 19:20:52 -0300701static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
702 struct sk_buff *skb)
703{
704 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
705
706 BT_DBG("%s status 0x%x", hdev->name, rp->status);
707
708 if (rp->status)
709 return;
710
711 memcpy(hdev->extfeatures, rp->features, 8);
712
713 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
714}
715
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200716static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
717 struct sk_buff *skb)
718{
719 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
720
721 BT_DBG("%s status 0x%x", hdev->name, rp->status);
722
723 if (rp->status)
724 return;
725
726 hdev->flow_ctl_mode = rp->mode;
727
728 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
729}
730
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200731static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
732{
733 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
734
735 BT_DBG("%s status 0x%x", hdev->name, rp->status);
736
737 if (rp->status)
738 return;
739
740 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
741 hdev->sco_mtu = rp->sco_mtu;
742 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
743 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
744
745 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
746 hdev->sco_mtu = 64;
747 hdev->sco_pkts = 8;
748 }
749
750 hdev->acl_cnt = hdev->acl_pkts;
751 hdev->sco_cnt = hdev->sco_pkts;
752
753 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
754 hdev->acl_mtu, hdev->acl_pkts,
755 hdev->sco_mtu, hdev->sco_pkts);
756}
757
758static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
759{
760 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
761
762 BT_DBG("%s status 0x%x", hdev->name, rp->status);
763
764 if (!rp->status)
765 bacpy(&hdev->bdaddr, &rp->bdaddr);
766
Johan Hedberg23bb5762010-12-21 23:01:27 +0200767 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
768}
769
770static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
771{
772 __u8 status = *((__u8 *) skb->data);
773
774 BT_DBG("%s status 0x%x", hdev->name, status);
775
776 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200777}
778
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300779static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
780 struct sk_buff *skb)
781{
782 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
783
784 BT_DBG("%s status 0x%x", hdev->name, rp->status);
785
786 if (rp->status)
787 return;
788
789 hdev->amp_status = rp->amp_status;
790 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
791 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
792 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
793 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
794 hdev->amp_type = rp->amp_type;
795 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
796 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
797 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
798 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
799
800 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
801}
802
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200803static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
804 struct sk_buff *skb)
805{
806 __u8 status = *((__u8 *) skb->data);
807
808 BT_DBG("%s status 0x%x", hdev->name, status);
809
810 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
811}
812
Johan Hedbergd5859e22011-01-25 01:19:58 +0200813static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
814{
815 __u8 status = *((__u8 *) skb->data);
816
817 BT_DBG("%s status 0x%x", hdev->name, status);
818
819 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
820}
821
822static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
823 struct sk_buff *skb)
824{
825 __u8 status = *((__u8 *) skb->data);
826
827 BT_DBG("%s status 0x%x", hdev->name, status);
828
829 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
830}
831
832static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
833 struct sk_buff *skb)
834{
835 __u8 status = *((__u8 *) skb->data);
836
837 BT_DBG("%s status 0x%x", hdev->name, status);
838
839 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
840}
841
842static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
843{
844 __u8 status = *((__u8 *) skb->data);
845
846 BT_DBG("%s status 0x%x", hdev->name, status);
847
848 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
849}
850
Johan Hedberg980e1a52011-01-22 06:10:07 +0200851static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
852{
853 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
854 struct hci_cp_pin_code_reply *cp;
855 struct hci_conn *conn;
856
857 BT_DBG("%s status 0x%x", hdev->name, rp->status);
858
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200859 hci_dev_lock(hdev);
860
Johan Hedberg980e1a52011-01-22 06:10:07 +0200861 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200862 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200863
864 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200865 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200866
867 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
868 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200869 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200870
871 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
872 if (conn)
873 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200874
875unlock:
876 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200877}
878
879static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
880{
881 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
882
883 BT_DBG("%s status 0x%x", hdev->name, rp->status);
884
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200885 hci_dev_lock(hdev);
886
Johan Hedberg980e1a52011-01-22 06:10:07 +0200887 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200888 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200889 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200890
891 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200892}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200893
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300894static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
895 struct sk_buff *skb)
896{
897 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
898
899 BT_DBG("%s status 0x%x", hdev->name, rp->status);
900
901 if (rp->status)
902 return;
903
904 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
905 hdev->le_pkts = rp->le_max_pkt;
906
907 hdev->le_cnt = hdev->le_pkts;
908
909 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
910
911 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
912}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200913
Johan Hedberga5c29682011-02-19 12:05:57 -0300914static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
915{
916 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
917
918 BT_DBG("%s status 0x%x", hdev->name, rp->status);
919
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200920 hci_dev_lock(hdev);
921
Johan Hedberga5c29682011-02-19 12:05:57 -0300922 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200923 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300924 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200925
926 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300927}
928
929static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
930 struct sk_buff *skb)
931{
932 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
933
934 BT_DBG("%s status 0x%x", hdev->name, rp->status);
935
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200936 hci_dev_lock(hdev);
937
Johan Hedberga5c29682011-02-19 12:05:57 -0300938 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200939 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300940 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200941
942 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300943}
944
Brian Gix1143d452011-11-23 08:28:34 -0800945static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
946{
947 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
948
949 BT_DBG("%s status 0x%x", hdev->name, rp->status);
950
951 hci_dev_lock(hdev);
952
953 if (test_bit(HCI_MGMT, &hdev->flags))
954 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr,
955 rp->status);
956
957 hci_dev_unlock(hdev);
958}
959
960static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
961 struct sk_buff *skb)
962{
963 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
964
965 BT_DBG("%s status 0x%x", hdev->name, rp->status);
966
967 hci_dev_lock(hdev);
968
969 if (test_bit(HCI_MGMT, &hdev->flags))
970 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
971 rp->status);
972
973 hci_dev_unlock(hdev);
974}
975
Szymon Jancc35938b2011-03-22 13:12:21 +0100976static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
977 struct sk_buff *skb)
978{
979 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
980
981 BT_DBG("%s status 0x%x", hdev->name, rp->status);
982
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200983 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200984 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100985 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200986 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100987}
988
Andre Guedes07f7fa52011-12-02 21:13:31 +0900989static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
990{
991 __u8 status = *((__u8 *) skb->data);
992
993 BT_DBG("%s status 0x%x", hdev->name, status);
994}
995
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300996static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
997 struct sk_buff *skb)
998{
999 struct hci_cp_le_set_scan_enable *cp;
1000 __u8 status = *((__u8 *) skb->data);
1001
1002 BT_DBG("%s status 0x%x", hdev->name, status);
1003
1004 if (status)
1005 return;
1006
1007 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1008 if (!cp)
1009 return;
1010
Andre Guedes35815082011-05-26 16:23:53 -03001011 if (cp->enable == 0x01) {
Andre Guedesd23264a2011-11-25 20:53:38 -03001012 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1013
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001014 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001015
1016 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001017 hci_adv_entries_clear(hdev);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001018 hci_dev_unlock(hdev);
Andre Guedes35815082011-05-26 16:23:53 -03001019 } else if (cp->enable == 0x00) {
Andre Guedesd23264a2011-11-25 20:53:38 -03001020 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1021
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001022 cancel_delayed_work_sync(&hdev->adv_work);
1023 queue_delayed_work(hdev->workqueue, &hdev->adv_work,
1024 jiffies + ADV_CLEAR_TIMEOUT);
Andre Guedes35815082011-05-26 16:23:53 -03001025 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001026}
1027
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001028static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1029{
1030 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1031
1032 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1033
1034 if (rp->status)
1035 return;
1036
1037 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1038}
1039
1040static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1041{
1042 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1043
1044 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1045
1046 if (rp->status)
1047 return;
1048
1049 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1050}
1051
Andre Guedesf9b49302011-06-30 19:20:53 -03001052static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1053 struct sk_buff *skb)
1054{
1055 struct hci_cp_read_local_ext_features cp;
1056 __u8 status = *((__u8 *) skb->data);
1057
1058 BT_DBG("%s status 0x%x", hdev->name, status);
1059
1060 if (status)
1061 return;
1062
1063 cp.page = 0x01;
1064 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1065}
1066
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001067static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1068{
1069 BT_DBG("%s status 0x%x", hdev->name, status);
1070
1071 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001072 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001073 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001074 hci_dev_lock(hdev);
Johan Hedberg164a6e72011-11-01 17:06:44 +02001075 if (test_bit(HCI_MGMT, &hdev->flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001076 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001077 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001078 return;
1079 }
1080
Andre Guedes89352e72011-11-04 14:16:53 -03001081 set_bit(HCI_INQUIRY, &hdev->flags);
1082
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001083 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001084 mgmt_discovering(hdev, 1);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001085 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001086}
1087
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1089{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001090 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001093 BT_DBG("%s status 0x%x", hdev->name, status);
1094
1095 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 if (!cp)
1097 return;
1098
1099 hci_dev_lock(hdev);
1100
1101 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1102
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001103 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104
1105 if (status) {
1106 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001107 if (status != 0x0c || conn->attempt > 2) {
1108 conn->state = BT_CLOSED;
1109 hci_proto_connect_cfm(conn, status);
1110 hci_conn_del(conn);
1111 } else
1112 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 }
1114 } else {
1115 if (!conn) {
1116 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1117 if (conn) {
1118 conn->out = 1;
1119 conn->link_mode |= HCI_LM_MASTER;
1120 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001121 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 }
1123 }
1124
1125 hci_dev_unlock(hdev);
1126}
1127
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001128static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001130 struct hci_cp_add_sco *cp;
1131 struct hci_conn *acl, *sco;
1132 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001134 BT_DBG("%s status 0x%x", hdev->name, status);
1135
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001136 if (!status)
1137 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001139 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1140 if (!cp)
1141 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001143 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001145 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001146
1147 hci_dev_lock(hdev);
1148
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001149 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001150 if (acl) {
1151 sco = acl->link;
1152 if (sco) {
1153 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001154
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001155 hci_proto_connect_cfm(sco, status);
1156 hci_conn_del(sco);
1157 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001158 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001159
1160 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161}
1162
Marcel Holtmannf8558552008-07-14 20:13:49 +02001163static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1164{
1165 struct hci_cp_auth_requested *cp;
1166 struct hci_conn *conn;
1167
1168 BT_DBG("%s status 0x%x", hdev->name, status);
1169
1170 if (!status)
1171 return;
1172
1173 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1174 if (!cp)
1175 return;
1176
1177 hci_dev_lock(hdev);
1178
1179 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1180 if (conn) {
1181 if (conn->state == BT_CONFIG) {
1182 hci_proto_connect_cfm(conn, status);
1183 hci_conn_put(conn);
1184 }
1185 }
1186
1187 hci_dev_unlock(hdev);
1188}
1189
1190static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1191{
1192 struct hci_cp_set_conn_encrypt *cp;
1193 struct hci_conn *conn;
1194
1195 BT_DBG("%s status 0x%x", hdev->name, status);
1196
1197 if (!status)
1198 return;
1199
1200 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1201 if (!cp)
1202 return;
1203
1204 hci_dev_lock(hdev);
1205
1206 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1207 if (conn) {
1208 if (conn->state == BT_CONFIG) {
1209 hci_proto_connect_cfm(conn, status);
1210 hci_conn_put(conn);
1211 }
1212 }
1213
1214 hci_dev_unlock(hdev);
1215}
1216
Johan Hedberg127178d2010-11-18 22:22:29 +02001217static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001218 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001219{
Johan Hedberg392599b2010-11-18 22:22:28 +02001220 if (conn->state != BT_CONFIG || !conn->out)
1221 return 0;
1222
Johan Hedberg765c2a92011-01-19 12:06:52 +05301223 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001224 return 0;
1225
1226 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001227 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedberg392599b2010-11-18 22:22:28 +02001228 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001229 conn->pending_sec_level != BT_SECURITY_HIGH &&
1230 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001231 return 0;
1232
Johan Hedberg392599b2010-11-18 22:22:28 +02001233 return 1;
1234}
1235
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001236static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1237{
Johan Hedberg127178d2010-11-18 22:22:29 +02001238 struct hci_cp_remote_name_req *cp;
1239 struct hci_conn *conn;
1240
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001241 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001242
1243 /* If successful wait for the name req complete event before
1244 * checking for the need to do authentication */
1245 if (!status)
1246 return;
1247
1248 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1249 if (!cp)
1250 return;
1251
1252 hci_dev_lock(hdev);
1253
1254 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001255 if (!conn)
1256 goto unlock;
1257
1258 if (!hci_outgoing_auth_needed(hdev, conn))
1259 goto unlock;
1260
1261 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001262 struct hci_cp_auth_requested cp;
1263 cp.handle = __cpu_to_le16(conn->handle);
1264 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1265 }
1266
Johan Hedberg79c6c702011-04-28 11:28:55 -07001267unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001268 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001269}
1270
Marcel Holtmann769be972008-07-14 20:13:49 +02001271static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1272{
1273 struct hci_cp_read_remote_features *cp;
1274 struct hci_conn *conn;
1275
1276 BT_DBG("%s status 0x%x", hdev->name, status);
1277
1278 if (!status)
1279 return;
1280
1281 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1282 if (!cp)
1283 return;
1284
1285 hci_dev_lock(hdev);
1286
1287 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1288 if (conn) {
1289 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001290 hci_proto_connect_cfm(conn, status);
1291 hci_conn_put(conn);
1292 }
1293 }
1294
1295 hci_dev_unlock(hdev);
1296}
1297
1298static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1299{
1300 struct hci_cp_read_remote_ext_features *cp;
1301 struct hci_conn *conn;
1302
1303 BT_DBG("%s status 0x%x", hdev->name, status);
1304
1305 if (!status)
1306 return;
1307
1308 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1309 if (!cp)
1310 return;
1311
1312 hci_dev_lock(hdev);
1313
1314 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1315 if (conn) {
1316 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001317 hci_proto_connect_cfm(conn, status);
1318 hci_conn_put(conn);
1319 }
1320 }
1321
1322 hci_dev_unlock(hdev);
1323}
1324
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001325static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1326{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001327 struct hci_cp_setup_sync_conn *cp;
1328 struct hci_conn *acl, *sco;
1329 __u16 handle;
1330
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001331 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001332
1333 if (!status)
1334 return;
1335
1336 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1337 if (!cp)
1338 return;
1339
1340 handle = __le16_to_cpu(cp->handle);
1341
1342 BT_DBG("%s handle %d", hdev->name, handle);
1343
1344 hci_dev_lock(hdev);
1345
1346 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001347 if (acl) {
1348 sco = acl->link;
1349 if (sco) {
1350 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001351
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001352 hci_proto_connect_cfm(sco, status);
1353 hci_conn_del(sco);
1354 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001355 }
1356
1357 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001358}
1359
1360static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1361{
1362 struct hci_cp_sniff_mode *cp;
1363 struct hci_conn *conn;
1364
1365 BT_DBG("%s status 0x%x", hdev->name, status);
1366
1367 if (!status)
1368 return;
1369
1370 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1371 if (!cp)
1372 return;
1373
1374 hci_dev_lock(hdev);
1375
1376 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001377 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001378 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1379
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001380 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1381 hci_sco_setup(conn, status);
1382 }
1383
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001384 hci_dev_unlock(hdev);
1385}
1386
1387static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1388{
1389 struct hci_cp_exit_sniff_mode *cp;
1390 struct hci_conn *conn;
1391
1392 BT_DBG("%s status 0x%x", hdev->name, status);
1393
1394 if (!status)
1395 return;
1396
1397 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1398 if (!cp)
1399 return;
1400
1401 hci_dev_lock(hdev);
1402
1403 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001404 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001405 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1406
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001407 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1408 hci_sco_setup(conn, status);
1409 }
1410
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001411 hci_dev_unlock(hdev);
1412}
1413
Ville Tervofcd89c02011-02-10 22:38:47 -03001414static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1415{
1416 struct hci_cp_le_create_conn *cp;
1417 struct hci_conn *conn;
1418
1419 BT_DBG("%s status 0x%x", hdev->name, status);
1420
1421 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1422 if (!cp)
1423 return;
1424
1425 hci_dev_lock(hdev);
1426
1427 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1428
1429 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1430 conn);
1431
1432 if (status) {
1433 if (conn && conn->state == BT_CONNECT) {
1434 conn->state = BT_CLOSED;
1435 hci_proto_connect_cfm(conn, status);
1436 hci_conn_del(conn);
1437 }
1438 } else {
1439 if (!conn) {
1440 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001441 if (conn) {
1442 conn->dst_type = cp->peer_addr_type;
Ville Tervofcd89c02011-02-10 22:38:47 -03001443 conn->out = 1;
Andre Guedes29b79882011-05-31 14:20:54 -03001444 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001445 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001446 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001447 }
1448 }
1449
1450 hci_dev_unlock(hdev);
1451}
1452
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001453static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1454{
1455 BT_DBG("%s status 0x%x", hdev->name, status);
1456}
1457
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001458static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1459{
1460 __u8 status = *((__u8 *) skb->data);
1461
1462 BT_DBG("%s status %d", hdev->name, status);
1463
Johan Hedberg23bb5762010-12-21 23:01:27 +02001464 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001465
1466 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001467
1468 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1469 return;
1470
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001471 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001472 mgmt_discovering(hdev, 0);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001473 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001474}
1475
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1477{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001478 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001479 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480 int num_rsp = *((__u8 *) skb->data);
1481
1482 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1483
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001484 if (!num_rsp)
1485 return;
1486
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001488
Johan Hedberge17acd42011-03-30 23:57:16 +03001489 for (; num_rsp; num_rsp--, info++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490 bacpy(&data.bdaddr, &info->bdaddr);
1491 data.pscan_rep_mode = info->pscan_rep_mode;
1492 data.pscan_period_mode = info->pscan_period_mode;
1493 data.pscan_mode = info->pscan_mode;
1494 memcpy(data.dev_class, info->dev_class, 3);
1495 data.clock_offset = info->clock_offset;
1496 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001497 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02001499 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg4c659c32011-11-07 23:13:39 +02001500 info->dev_class, 0, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001502
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 hci_dev_unlock(hdev);
1504}
1505
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001506static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001508 struct hci_ev_conn_complete *ev = (void *) skb->data;
1509 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001511 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001512
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001514
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001515 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001516 if (!conn) {
1517 if (ev->link_type != SCO_LINK)
1518 goto unlock;
1519
1520 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1521 if (!conn)
1522 goto unlock;
1523
1524 conn->type = SCO_LINK;
1525 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001526
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001527 if (!ev->status) {
1528 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001529
1530 if (conn->type == ACL_LINK) {
1531 conn->state = BT_CONFIG;
1532 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001533 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg48264f02011-11-09 13:58:58 +02001534 mgmt_connected(hdev, &ev->bdaddr, conn->type,
1535 conn->dst_type);
Marcel Holtmann769be972008-07-14 20:13:49 +02001536 } else
1537 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001538
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001539 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001540 hci_conn_add_sysfs(conn);
1541
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001542 if (test_bit(HCI_AUTH, &hdev->flags))
1543 conn->link_mode |= HCI_LM_AUTH;
1544
1545 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1546 conn->link_mode |= HCI_LM_ENCRYPT;
1547
1548 /* Get remote features */
1549 if (conn->type == ACL_LINK) {
1550 struct hci_cp_read_remote_features cp;
1551 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001552 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1553 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001554 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001555
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001556 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001557 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001558 struct hci_cp_change_conn_ptype cp;
1559 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001560 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1561 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1562 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001563 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001564 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001565 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001566 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001567 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001568 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001569 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001570
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001571 if (conn->type == ACL_LINK)
1572 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001573
Marcel Holtmann769be972008-07-14 20:13:49 +02001574 if (ev->status) {
1575 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001576 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001577 } else if (ev->link_type != ACL_LINK)
1578 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001579
1580unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001582
1583 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584}
1585
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1587{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001588 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 int mask = hdev->link_mode;
1590
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001591 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1592 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593
1594 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1595
Szymon Janc138d22e2011-02-17 16:44:23 +01001596 if ((mask & HCI_LM_ACCEPT) &&
1597 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001599 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601
1602 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001603
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001604 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1605 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001606 memcpy(ie->data.dev_class, ev->dev_class, 3);
1607
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1609 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001610 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1611 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001612 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 hci_dev_unlock(hdev);
1614 return;
1615 }
1616 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001617
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 memcpy(conn->dev_class, ev->dev_class, 3);
1619 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001620
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 hci_dev_unlock(hdev);
1622
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001623 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1624 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001626 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001628 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1629 cp.role = 0x00; /* Become master */
1630 else
1631 cp.role = 0x01; /* Remain slave */
1632
1633 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1634 sizeof(cp), &cp);
1635 } else {
1636 struct hci_cp_accept_sync_conn_req cp;
1637
1638 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001639 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001640
1641 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1642 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1643 cp.max_latency = cpu_to_le16(0xffff);
1644 cp.content_format = cpu_to_le16(hdev->voice_setting);
1645 cp.retrans_effort = 0xff;
1646
1647 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1648 sizeof(cp), &cp);
1649 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 } else {
1651 /* Connection rejected */
1652 struct hci_cp_reject_conn_req cp;
1653
1654 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001655 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001656 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 }
1658}
1659
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1661{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001662 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001663 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664
1665 BT_DBG("%s status %d", hdev->name, ev->status);
1666
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667 hci_dev_lock(hdev);
1668
Marcel Holtmann04837f62006-07-03 10:02:33 +02001669 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001670 if (!conn)
1671 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001672
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001673 if (ev->status == 0)
1674 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001676 if (conn->type == ACL_LINK || conn->type == LE_LINK) {
1677 if (ev->status != 0)
1678 mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
1679 else
1680 mgmt_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001681 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001682 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001683
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001684 if (ev->status == 0) {
1685 hci_proto_disconn_cfm(conn, ev->reason);
1686 hci_conn_del(conn);
1687 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001688
1689unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 hci_dev_unlock(hdev);
1691}
1692
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001693static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1694{
1695 struct hci_ev_auth_complete *ev = (void *) skb->data;
1696 struct hci_conn *conn;
1697
1698 BT_DBG("%s status %d", hdev->name, ev->status);
1699
1700 hci_dev_lock(hdev);
1701
1702 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001703 if (!conn)
1704 goto unlock;
1705
1706 if (!ev->status) {
1707 if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) &&
1708 test_bit(HCI_CONN_REAUTH_PEND, &conn->pend)) {
1709 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001710 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001711 conn->link_mode |= HCI_LM_AUTH;
1712 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001713 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001714 } else {
Johan Hedberg744cf192011-11-08 20:40:14 +02001715 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001716 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001717
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001718 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1719 clear_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001720
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001721 if (conn->state == BT_CONFIG) {
1722 if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) {
1723 struct hci_cp_set_conn_encrypt cp;
1724 cp.handle = ev->handle;
1725 cp.encrypt = 0x01;
1726 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1727 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001728 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001729 conn->state = BT_CONNECTED;
1730 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001731 hci_conn_put(conn);
1732 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001733 } else {
1734 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001735
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001736 hci_conn_hold(conn);
1737 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1738 hci_conn_put(conn);
1739 }
1740
1741 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1742 if (!ev->status) {
1743 struct hci_cp_set_conn_encrypt cp;
1744 cp.handle = ev->handle;
1745 cp.encrypt = 0x01;
1746 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1747 &cp);
1748 } else {
1749 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1750 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001751 }
1752 }
1753
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001754unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001755 hci_dev_unlock(hdev);
1756}
1757
1758static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1759{
Johan Hedberg127178d2010-11-18 22:22:29 +02001760 struct hci_ev_remote_name *ev = (void *) skb->data;
1761 struct hci_conn *conn;
1762
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001763 BT_DBG("%s", hdev->name);
1764
1765 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001766
1767 hci_dev_lock(hdev);
1768
Johan Hedberga88a9652011-03-30 13:18:12 +03001769 if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001770 mgmt_remote_name(hdev, &ev->bdaddr, ev->name);
Johan Hedberga88a9652011-03-30 13:18:12 +03001771
Johan Hedberg127178d2010-11-18 22:22:29 +02001772 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001773 if (!conn)
1774 goto unlock;
1775
1776 if (!hci_outgoing_auth_needed(hdev, conn))
1777 goto unlock;
1778
1779 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001780 struct hci_cp_auth_requested cp;
1781 cp.handle = __cpu_to_le16(conn->handle);
1782 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1783 }
1784
Johan Hedberg79c6c702011-04-28 11:28:55 -07001785unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001786 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001787}
1788
1789static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1790{
1791 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1792 struct hci_conn *conn;
1793
1794 BT_DBG("%s status %d", hdev->name, ev->status);
1795
1796 hci_dev_lock(hdev);
1797
1798 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1799 if (conn) {
1800 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001801 if (ev->encrypt) {
1802 /* Encryption implies authentication */
1803 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001804 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001805 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001806 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001807 conn->link_mode &= ~HCI_LM_ENCRYPT;
1808 }
1809
1810 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1811
Marcel Holtmannf8558552008-07-14 20:13:49 +02001812 if (conn->state == BT_CONFIG) {
1813 if (!ev->status)
1814 conn->state = BT_CONNECTED;
1815
1816 hci_proto_connect_cfm(conn, ev->status);
1817 hci_conn_put(conn);
1818 } else
1819 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001820 }
1821
1822 hci_dev_unlock(hdev);
1823}
1824
1825static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1826{
1827 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1828 struct hci_conn *conn;
1829
1830 BT_DBG("%s status %d", hdev->name, ev->status);
1831
1832 hci_dev_lock(hdev);
1833
1834 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1835 if (conn) {
1836 if (!ev->status)
1837 conn->link_mode |= HCI_LM_SECURE;
1838
1839 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1840
1841 hci_key_change_cfm(conn, ev->status);
1842 }
1843
1844 hci_dev_unlock(hdev);
1845}
1846
1847static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1848{
1849 struct hci_ev_remote_features *ev = (void *) skb->data;
1850 struct hci_conn *conn;
1851
1852 BT_DBG("%s status %d", hdev->name, ev->status);
1853
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001854 hci_dev_lock(hdev);
1855
1856 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001857 if (!conn)
1858 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001859
Johan Hedbergccd556f2010-11-10 17:11:51 +02001860 if (!ev->status)
1861 memcpy(conn->features, ev->features, 8);
1862
1863 if (conn->state != BT_CONFIG)
1864 goto unlock;
1865
1866 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1867 struct hci_cp_read_remote_ext_features cp;
1868 cp.handle = ev->handle;
1869 cp.page = 0x01;
1870 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001871 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001872 goto unlock;
1873 }
1874
Johan Hedberg127178d2010-11-18 22:22:29 +02001875 if (!ev->status) {
1876 struct hci_cp_remote_name_req cp;
1877 memset(&cp, 0, sizeof(cp));
1878 bacpy(&cp.bdaddr, &conn->dst);
1879 cp.pscan_rep_mode = 0x02;
1880 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1881 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001882
Johan Hedberg127178d2010-11-18 22:22:29 +02001883 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001884 conn->state = BT_CONNECTED;
1885 hci_proto_connect_cfm(conn, ev->status);
1886 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001887 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001888
Johan Hedbergccd556f2010-11-10 17:11:51 +02001889unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001890 hci_dev_unlock(hdev);
1891}
1892
1893static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1894{
1895 BT_DBG("%s", hdev->name);
1896}
1897
1898static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1899{
1900 BT_DBG("%s", hdev->name);
1901}
1902
1903static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1904{
1905 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1906 __u16 opcode;
1907
1908 skb_pull(skb, sizeof(*ev));
1909
1910 opcode = __le16_to_cpu(ev->opcode);
1911
1912 switch (opcode) {
1913 case HCI_OP_INQUIRY_CANCEL:
1914 hci_cc_inquiry_cancel(hdev, skb);
1915 break;
1916
1917 case HCI_OP_EXIT_PERIODIC_INQ:
1918 hci_cc_exit_periodic_inq(hdev, skb);
1919 break;
1920
1921 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1922 hci_cc_remote_name_req_cancel(hdev, skb);
1923 break;
1924
1925 case HCI_OP_ROLE_DISCOVERY:
1926 hci_cc_role_discovery(hdev, skb);
1927 break;
1928
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001929 case HCI_OP_READ_LINK_POLICY:
1930 hci_cc_read_link_policy(hdev, skb);
1931 break;
1932
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001933 case HCI_OP_WRITE_LINK_POLICY:
1934 hci_cc_write_link_policy(hdev, skb);
1935 break;
1936
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001937 case HCI_OP_READ_DEF_LINK_POLICY:
1938 hci_cc_read_def_link_policy(hdev, skb);
1939 break;
1940
1941 case HCI_OP_WRITE_DEF_LINK_POLICY:
1942 hci_cc_write_def_link_policy(hdev, skb);
1943 break;
1944
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001945 case HCI_OP_RESET:
1946 hci_cc_reset(hdev, skb);
1947 break;
1948
1949 case HCI_OP_WRITE_LOCAL_NAME:
1950 hci_cc_write_local_name(hdev, skb);
1951 break;
1952
1953 case HCI_OP_READ_LOCAL_NAME:
1954 hci_cc_read_local_name(hdev, skb);
1955 break;
1956
1957 case HCI_OP_WRITE_AUTH_ENABLE:
1958 hci_cc_write_auth_enable(hdev, skb);
1959 break;
1960
1961 case HCI_OP_WRITE_ENCRYPT_MODE:
1962 hci_cc_write_encrypt_mode(hdev, skb);
1963 break;
1964
1965 case HCI_OP_WRITE_SCAN_ENABLE:
1966 hci_cc_write_scan_enable(hdev, skb);
1967 break;
1968
1969 case HCI_OP_READ_CLASS_OF_DEV:
1970 hci_cc_read_class_of_dev(hdev, skb);
1971 break;
1972
1973 case HCI_OP_WRITE_CLASS_OF_DEV:
1974 hci_cc_write_class_of_dev(hdev, skb);
1975 break;
1976
1977 case HCI_OP_READ_VOICE_SETTING:
1978 hci_cc_read_voice_setting(hdev, skb);
1979 break;
1980
1981 case HCI_OP_WRITE_VOICE_SETTING:
1982 hci_cc_write_voice_setting(hdev, skb);
1983 break;
1984
1985 case HCI_OP_HOST_BUFFER_SIZE:
1986 hci_cc_host_buffer_size(hdev, skb);
1987 break;
1988
Marcel Holtmann333140b2008-07-14 20:13:48 +02001989 case HCI_OP_READ_SSP_MODE:
1990 hci_cc_read_ssp_mode(hdev, skb);
1991 break;
1992
1993 case HCI_OP_WRITE_SSP_MODE:
1994 hci_cc_write_ssp_mode(hdev, skb);
1995 break;
1996
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001997 case HCI_OP_READ_LOCAL_VERSION:
1998 hci_cc_read_local_version(hdev, skb);
1999 break;
2000
2001 case HCI_OP_READ_LOCAL_COMMANDS:
2002 hci_cc_read_local_commands(hdev, skb);
2003 break;
2004
2005 case HCI_OP_READ_LOCAL_FEATURES:
2006 hci_cc_read_local_features(hdev, skb);
2007 break;
2008
Andre Guedes971e3a42011-06-30 19:20:52 -03002009 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2010 hci_cc_read_local_ext_features(hdev, skb);
2011 break;
2012
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002013 case HCI_OP_READ_BUFFER_SIZE:
2014 hci_cc_read_buffer_size(hdev, skb);
2015 break;
2016
2017 case HCI_OP_READ_BD_ADDR:
2018 hci_cc_read_bd_addr(hdev, skb);
2019 break;
2020
Johan Hedberg23bb5762010-12-21 23:01:27 +02002021 case HCI_OP_WRITE_CA_TIMEOUT:
2022 hci_cc_write_ca_timeout(hdev, skb);
2023 break;
2024
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002025 case HCI_OP_READ_FLOW_CONTROL_MODE:
2026 hci_cc_read_flow_control_mode(hdev, skb);
2027 break;
2028
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002029 case HCI_OP_READ_LOCAL_AMP_INFO:
2030 hci_cc_read_local_amp_info(hdev, skb);
2031 break;
2032
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002033 case HCI_OP_DELETE_STORED_LINK_KEY:
2034 hci_cc_delete_stored_link_key(hdev, skb);
2035 break;
2036
Johan Hedbergd5859e22011-01-25 01:19:58 +02002037 case HCI_OP_SET_EVENT_MASK:
2038 hci_cc_set_event_mask(hdev, skb);
2039 break;
2040
2041 case HCI_OP_WRITE_INQUIRY_MODE:
2042 hci_cc_write_inquiry_mode(hdev, skb);
2043 break;
2044
2045 case HCI_OP_READ_INQ_RSP_TX_POWER:
2046 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2047 break;
2048
2049 case HCI_OP_SET_EVENT_FLT:
2050 hci_cc_set_event_flt(hdev, skb);
2051 break;
2052
Johan Hedberg980e1a52011-01-22 06:10:07 +02002053 case HCI_OP_PIN_CODE_REPLY:
2054 hci_cc_pin_code_reply(hdev, skb);
2055 break;
2056
2057 case HCI_OP_PIN_CODE_NEG_REPLY:
2058 hci_cc_pin_code_neg_reply(hdev, skb);
2059 break;
2060
Szymon Jancc35938b2011-03-22 13:12:21 +01002061 case HCI_OP_READ_LOCAL_OOB_DATA:
2062 hci_cc_read_local_oob_data_reply(hdev, skb);
2063 break;
2064
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002065 case HCI_OP_LE_READ_BUFFER_SIZE:
2066 hci_cc_le_read_buffer_size(hdev, skb);
2067 break;
2068
Johan Hedberga5c29682011-02-19 12:05:57 -03002069 case HCI_OP_USER_CONFIRM_REPLY:
2070 hci_cc_user_confirm_reply(hdev, skb);
2071 break;
2072
2073 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2074 hci_cc_user_confirm_neg_reply(hdev, skb);
2075 break;
2076
Brian Gix1143d452011-11-23 08:28:34 -08002077 case HCI_OP_USER_PASSKEY_REPLY:
2078 hci_cc_user_passkey_reply(hdev, skb);
2079 break;
2080
2081 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2082 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002083
2084 case HCI_OP_LE_SET_SCAN_PARAM:
2085 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002086 break;
2087
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002088 case HCI_OP_LE_SET_SCAN_ENABLE:
2089 hci_cc_le_set_scan_enable(hdev, skb);
2090 break;
2091
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002092 case HCI_OP_LE_LTK_REPLY:
2093 hci_cc_le_ltk_reply(hdev, skb);
2094 break;
2095
2096 case HCI_OP_LE_LTK_NEG_REPLY:
2097 hci_cc_le_ltk_neg_reply(hdev, skb);
2098 break;
2099
Andre Guedesf9b49302011-06-30 19:20:53 -03002100 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2101 hci_cc_write_le_host_supported(hdev, skb);
2102 break;
2103
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002104 default:
2105 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2106 break;
2107 }
2108
Ville Tervo6bd32322011-02-16 16:32:41 +02002109 if (ev->opcode != HCI_OP_NOP)
2110 del_timer(&hdev->cmd_timer);
2111
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002112 if (ev->ncmd) {
2113 atomic_set(&hdev->cmd_cnt, 1);
2114 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002115 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002116 }
2117}
2118
2119static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2120{
2121 struct hci_ev_cmd_status *ev = (void *) skb->data;
2122 __u16 opcode;
2123
2124 skb_pull(skb, sizeof(*ev));
2125
2126 opcode = __le16_to_cpu(ev->opcode);
2127
2128 switch (opcode) {
2129 case HCI_OP_INQUIRY:
2130 hci_cs_inquiry(hdev, ev->status);
2131 break;
2132
2133 case HCI_OP_CREATE_CONN:
2134 hci_cs_create_conn(hdev, ev->status);
2135 break;
2136
2137 case HCI_OP_ADD_SCO:
2138 hci_cs_add_sco(hdev, ev->status);
2139 break;
2140
Marcel Holtmannf8558552008-07-14 20:13:49 +02002141 case HCI_OP_AUTH_REQUESTED:
2142 hci_cs_auth_requested(hdev, ev->status);
2143 break;
2144
2145 case HCI_OP_SET_CONN_ENCRYPT:
2146 hci_cs_set_conn_encrypt(hdev, ev->status);
2147 break;
2148
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002149 case HCI_OP_REMOTE_NAME_REQ:
2150 hci_cs_remote_name_req(hdev, ev->status);
2151 break;
2152
Marcel Holtmann769be972008-07-14 20:13:49 +02002153 case HCI_OP_READ_REMOTE_FEATURES:
2154 hci_cs_read_remote_features(hdev, ev->status);
2155 break;
2156
2157 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2158 hci_cs_read_remote_ext_features(hdev, ev->status);
2159 break;
2160
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002161 case HCI_OP_SETUP_SYNC_CONN:
2162 hci_cs_setup_sync_conn(hdev, ev->status);
2163 break;
2164
2165 case HCI_OP_SNIFF_MODE:
2166 hci_cs_sniff_mode(hdev, ev->status);
2167 break;
2168
2169 case HCI_OP_EXIT_SNIFF_MODE:
2170 hci_cs_exit_sniff_mode(hdev, ev->status);
2171 break;
2172
Johan Hedberg8962ee72011-01-20 12:40:27 +02002173 case HCI_OP_DISCONNECT:
2174 if (ev->status != 0)
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002175 mgmt_disconnect_failed(hdev, NULL, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002176 break;
2177
Ville Tervofcd89c02011-02-10 22:38:47 -03002178 case HCI_OP_LE_CREATE_CONN:
2179 hci_cs_le_create_conn(hdev, ev->status);
2180 break;
2181
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002182 case HCI_OP_LE_START_ENC:
2183 hci_cs_le_start_enc(hdev, ev->status);
2184 break;
2185
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002186 default:
2187 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2188 break;
2189 }
2190
Ville Tervo6bd32322011-02-16 16:32:41 +02002191 if (ev->opcode != HCI_OP_NOP)
2192 del_timer(&hdev->cmd_timer);
2193
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002194 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002195 atomic_set(&hdev->cmd_cnt, 1);
2196 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002197 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002198 }
2199}
2200
2201static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2202{
2203 struct hci_ev_role_change *ev = (void *) skb->data;
2204 struct hci_conn *conn;
2205
2206 BT_DBG("%s status %d", hdev->name, ev->status);
2207
2208 hci_dev_lock(hdev);
2209
2210 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2211 if (conn) {
2212 if (!ev->status) {
2213 if (ev->role)
2214 conn->link_mode &= ~HCI_LM_MASTER;
2215 else
2216 conn->link_mode |= HCI_LM_MASTER;
2217 }
2218
2219 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
2220
2221 hci_role_switch_cfm(conn, ev->status, ev->role);
2222 }
2223
2224 hci_dev_unlock(hdev);
2225}
2226
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2228{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002229 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002230 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 int i;
2232
2233 skb_pull(skb, sizeof(*ev));
2234
2235 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2236
2237 if (skb->len < ev->num_hndl * 4) {
2238 BT_DBG("%s bad parameters", hdev->name);
2239 return;
2240 }
2241
2242 tasklet_disable(&hdev->tx_task);
2243
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002244 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245 struct hci_conn *conn;
2246 __u16 handle, count;
2247
Harvey Harrison83985312008-05-02 16:25:46 -07002248 handle = get_unaligned_le16(ptr++);
2249 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250
2251 conn = hci_conn_hash_lookup_handle(hdev, handle);
2252 if (conn) {
2253 conn->sent -= count;
2254
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002255 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002256 hdev->acl_cnt += count;
2257 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258 hdev->acl_cnt = hdev->acl_pkts;
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002259 } else if (conn->type == LE_LINK) {
2260 if (hdev->le_pkts) {
2261 hdev->le_cnt += count;
2262 if (hdev->le_cnt > hdev->le_pkts)
2263 hdev->le_cnt = hdev->le_pkts;
2264 } else {
2265 hdev->acl_cnt += count;
2266 if (hdev->acl_cnt > hdev->acl_pkts)
2267 hdev->acl_cnt = hdev->acl_pkts;
2268 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002269 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002270 hdev->sco_cnt += count;
2271 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002272 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002273 }
2274 }
2275 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002276
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002277 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278
2279 tasklet_enable(&hdev->tx_task);
2280}
2281
Marcel Holtmann04837f62006-07-03 10:02:33 +02002282static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002283{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002284 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002285 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286
2287 BT_DBG("%s status %d", hdev->name, ev->status);
2288
2289 hci_dev_lock(hdev);
2290
Marcel Holtmann04837f62006-07-03 10:02:33 +02002291 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2292 if (conn) {
2293 conn->mode = ev->mode;
2294 conn->interval = __le16_to_cpu(ev->interval);
2295
2296 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
2297 if (conn->mode == HCI_CM_ACTIVE)
2298 conn->power_save = 1;
2299 else
2300 conn->power_save = 0;
2301 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002302
2303 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
2304 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002305 }
2306
2307 hci_dev_unlock(hdev);
2308}
2309
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2311{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002312 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2313 struct hci_conn *conn;
2314
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002315 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002316
2317 hci_dev_lock(hdev);
2318
2319 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002320 if (!conn)
2321 goto unlock;
2322
2323 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002324 hci_conn_hold(conn);
2325 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2326 hci_conn_put(conn);
2327 }
2328
Johan Hedberg03b555e2011-01-04 15:40:05 +02002329 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
2330 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2331 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg582fbe92011-04-28 11:28:58 -07002332 else if (test_bit(HCI_MGMT, &hdev->flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002333 u8 secure;
2334
2335 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2336 secure = 1;
2337 else
2338 secure = 0;
2339
Johan Hedberg744cf192011-11-08 20:40:14 +02002340 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002341 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002342
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002343unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002344 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002345}
2346
Linus Torvalds1da177e2005-04-16 15:20:36 -07002347static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2348{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002349 struct hci_ev_link_key_req *ev = (void *) skb->data;
2350 struct hci_cp_link_key_reply cp;
2351 struct hci_conn *conn;
2352 struct link_key *key;
2353
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002354 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002355
2356 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
2357 return;
2358
2359 hci_dev_lock(hdev);
2360
2361 key = hci_find_link_key(hdev, &ev->bdaddr);
2362 if (!key) {
2363 BT_DBG("%s link key not found for %s", hdev->name,
2364 batostr(&ev->bdaddr));
2365 goto not_found;
2366 }
2367
2368 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2369 batostr(&ev->bdaddr));
2370
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002371 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) &&
2372 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002373 BT_DBG("%s ignoring debug key", hdev->name);
2374 goto not_found;
2375 }
2376
2377 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002378 if (conn) {
2379 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2380 conn->auth_type != 0xff &&
2381 (conn->auth_type & 0x01)) {
2382 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2383 goto not_found;
2384 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002385
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002386 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2387 conn->pending_sec_level == BT_SECURITY_HIGH) {
2388 BT_DBG("%s ignoring key unauthenticated for high \
2389 security", hdev->name);
2390 goto not_found;
2391 }
2392
2393 conn->key_type = key->type;
2394 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002395 }
2396
2397 bacpy(&cp.bdaddr, &ev->bdaddr);
2398 memcpy(cp.link_key, key->val, 16);
2399
2400 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2401
2402 hci_dev_unlock(hdev);
2403
2404 return;
2405
2406not_found:
2407 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2408 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409}
2410
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2412{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002413 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2414 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002415 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002416
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002417 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002418
2419 hci_dev_lock(hdev);
2420
2421 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2422 if (conn) {
2423 hci_conn_hold(conn);
2424 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002425 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002426
2427 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2428 conn->key_type = ev->key_type;
2429
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002430 hci_conn_put(conn);
2431 }
2432
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002433 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002434 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002435 ev->key_type, pin_len);
2436
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002437 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438}
2439
Marcel Holtmann04837f62006-07-03 10:02:33 +02002440static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2441{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002442 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002443 struct hci_conn *conn;
2444
2445 BT_DBG("%s status %d", hdev->name, ev->status);
2446
2447 hci_dev_lock(hdev);
2448
2449 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450 if (conn && !ev->status) {
2451 struct inquiry_entry *ie;
2452
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002453 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2454 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455 ie->data.clock_offset = ev->clock_offset;
2456 ie->timestamp = jiffies;
2457 }
2458 }
2459
2460 hci_dev_unlock(hdev);
2461}
2462
Marcel Holtmanna8746412008-07-14 20:13:46 +02002463static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2464{
2465 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2466 struct hci_conn *conn;
2467
2468 BT_DBG("%s status %d", hdev->name, ev->status);
2469
2470 hci_dev_lock(hdev);
2471
2472 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2473 if (conn && !ev->status)
2474 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2475
2476 hci_dev_unlock(hdev);
2477}
2478
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002479static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2480{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002481 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002482 struct inquiry_entry *ie;
2483
2484 BT_DBG("%s", hdev->name);
2485
2486 hci_dev_lock(hdev);
2487
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002488 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2489 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002490 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2491 ie->timestamp = jiffies;
2492 }
2493
2494 hci_dev_unlock(hdev);
2495}
2496
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002497static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2498{
2499 struct inquiry_data data;
2500 int num_rsp = *((__u8 *) skb->data);
2501
2502 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2503
2504 if (!num_rsp)
2505 return;
2506
2507 hci_dev_lock(hdev);
2508
2509 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002510 struct inquiry_info_with_rssi_and_pscan_mode *info;
2511 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002512
Johan Hedberge17acd42011-03-30 23:57:16 +03002513 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002514 bacpy(&data.bdaddr, &info->bdaddr);
2515 data.pscan_rep_mode = info->pscan_rep_mode;
2516 data.pscan_period_mode = info->pscan_period_mode;
2517 data.pscan_mode = info->pscan_mode;
2518 memcpy(data.dev_class, info->dev_class, 3);
2519 data.clock_offset = info->clock_offset;
2520 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002521 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002522 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002523 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002524 info->dev_class, info->rssi,
2525 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002526 }
2527 } else {
2528 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2529
Johan Hedberge17acd42011-03-30 23:57:16 +03002530 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002531 bacpy(&data.bdaddr, &info->bdaddr);
2532 data.pscan_rep_mode = info->pscan_rep_mode;
2533 data.pscan_period_mode = info->pscan_period_mode;
2534 data.pscan_mode = 0x00;
2535 memcpy(data.dev_class, info->dev_class, 3);
2536 data.clock_offset = info->clock_offset;
2537 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002538 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002539 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002540 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002541 info->dev_class, info->rssi,
2542 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002543 }
2544 }
2545
2546 hci_dev_unlock(hdev);
2547}
2548
2549static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2550{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002551 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2552 struct hci_conn *conn;
2553
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002554 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002555
Marcel Holtmann41a96212008-07-14 20:13:48 +02002556 hci_dev_lock(hdev);
2557
2558 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002559 if (!conn)
2560 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002561
Johan Hedbergccd556f2010-11-10 17:11:51 +02002562 if (!ev->status && ev->page == 0x01) {
2563 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002564
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002565 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2566 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002567 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002568
Johan Hedbergccd556f2010-11-10 17:11:51 +02002569 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002570 }
2571
Johan Hedbergccd556f2010-11-10 17:11:51 +02002572 if (conn->state != BT_CONFIG)
2573 goto unlock;
2574
Johan Hedberg127178d2010-11-18 22:22:29 +02002575 if (!ev->status) {
2576 struct hci_cp_remote_name_req cp;
2577 memset(&cp, 0, sizeof(cp));
2578 bacpy(&cp.bdaddr, &conn->dst);
2579 cp.pscan_rep_mode = 0x02;
2580 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2581 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002582
Johan Hedberg127178d2010-11-18 22:22:29 +02002583 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002584 conn->state = BT_CONNECTED;
2585 hci_proto_connect_cfm(conn, ev->status);
2586 hci_conn_put(conn);
2587 }
2588
2589unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002590 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002591}
2592
2593static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2594{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002595 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2596 struct hci_conn *conn;
2597
2598 BT_DBG("%s status %d", hdev->name, ev->status);
2599
2600 hci_dev_lock(hdev);
2601
2602 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002603 if (!conn) {
2604 if (ev->link_type == ESCO_LINK)
2605 goto unlock;
2606
2607 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2608 if (!conn)
2609 goto unlock;
2610
2611 conn->type = SCO_LINK;
2612 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002613
Marcel Holtmann732547f2009-04-19 19:14:14 +02002614 switch (ev->status) {
2615 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002616 conn->handle = __le16_to_cpu(ev->handle);
2617 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002618
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002619 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002620 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002621 break;
2622
Stephen Coe705e5712010-02-16 11:29:44 -05002623 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002624 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002625 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002626 case 0x1f: /* Unspecified error */
2627 if (conn->out && conn->attempt < 2) {
2628 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2629 (hdev->esco_type & EDR_ESCO_MASK);
2630 hci_setup_sync(conn, conn->link->handle);
2631 goto unlock;
2632 }
2633 /* fall through */
2634
2635 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002636 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002637 break;
2638 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002639
2640 hci_proto_connect_cfm(conn, ev->status);
2641 if (ev->status)
2642 hci_conn_del(conn);
2643
2644unlock:
2645 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002646}
2647
2648static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2649{
2650 BT_DBG("%s", hdev->name);
2651}
2652
Marcel Holtmann04837f62006-07-03 10:02:33 +02002653static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2654{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002655 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002656
2657 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002658}
2659
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002660static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2661{
2662 struct inquiry_data data;
2663 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2664 int num_rsp = *((__u8 *) skb->data);
2665
2666 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2667
2668 if (!num_rsp)
2669 return;
2670
2671 hci_dev_lock(hdev);
2672
Johan Hedberge17acd42011-03-30 23:57:16 +03002673 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002674 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002675 data.pscan_rep_mode = info->pscan_rep_mode;
2676 data.pscan_period_mode = info->pscan_period_mode;
2677 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002678 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002679 data.clock_offset = info->clock_offset;
2680 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002681 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002682 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002683 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg4c659c32011-11-07 23:13:39 +02002684 info->dev_class, info->rssi, info->data);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002685 }
2686
2687 hci_dev_unlock(hdev);
2688}
2689
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002690static inline u8 hci_get_auth_req(struct hci_conn *conn)
2691{
2692 /* If remote requests dedicated bonding follow that lead */
2693 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2694 /* If both remote and local IO capabilities allow MITM
2695 * protection then require it, otherwise don't */
2696 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2697 return 0x02;
2698 else
2699 return 0x03;
2700 }
2701
2702 /* If remote requests no-bonding follow that lead */
2703 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002704 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002705
2706 return conn->auth_type;
2707}
2708
Marcel Holtmann04936842008-07-14 20:13:48 +02002709static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2710{
2711 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2712 struct hci_conn *conn;
2713
2714 BT_DBG("%s", hdev->name);
2715
2716 hci_dev_lock(hdev);
2717
2718 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002719 if (!conn)
2720 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002721
Johan Hedberg03b555e2011-01-04 15:40:05 +02002722 hci_conn_hold(conn);
2723
2724 if (!test_bit(HCI_MGMT, &hdev->flags))
2725 goto unlock;
2726
2727 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
2728 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002729 struct hci_cp_io_capability_reply cp;
2730
2731 bacpy(&cp.bdaddr, &ev->bdaddr);
2732 cp.capability = conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07002733 conn->auth_type = hci_get_auth_req(conn);
2734 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002735
Szymon Jancce85ee12011-03-22 13:12:23 +01002736 if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
2737 hci_find_remote_oob_data(hdev, &conn->dst))
2738 cp.oob_data = 0x01;
2739 else
2740 cp.oob_data = 0x00;
2741
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002742 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2743 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002744 } else {
2745 struct hci_cp_io_capability_neg_reply cp;
2746
2747 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002748 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02002749
2750 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2751 sizeof(cp), &cp);
2752 }
2753
2754unlock:
2755 hci_dev_unlock(hdev);
2756}
2757
2758static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2759{
2760 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2761 struct hci_conn *conn;
2762
2763 BT_DBG("%s", hdev->name);
2764
2765 hci_dev_lock(hdev);
2766
2767 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2768 if (!conn)
2769 goto unlock;
2770
Johan Hedberg03b555e2011-01-04 15:40:05 +02002771 conn->remote_cap = ev->capability;
2772 conn->remote_oob = ev->oob_data;
2773 conn->remote_auth = ev->authentication;
2774
2775unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002776 hci_dev_unlock(hdev);
2777}
2778
Johan Hedberga5c29682011-02-19 12:05:57 -03002779static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2780 struct sk_buff *skb)
2781{
2782 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002783 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07002784 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03002785
2786 BT_DBG("%s", hdev->name);
2787
2788 hci_dev_lock(hdev);
2789
Johan Hedberg7a828902011-04-28 11:28:53 -07002790 if (!test_bit(HCI_MGMT, &hdev->flags))
2791 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03002792
Johan Hedberg7a828902011-04-28 11:28:53 -07002793 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2794 if (!conn)
2795 goto unlock;
2796
2797 loc_mitm = (conn->auth_type & 0x01);
2798 rem_mitm = (conn->remote_auth & 0x01);
2799
2800 /* If we require MITM but the remote device can't provide that
2801 * (it has NoInputNoOutput) then reject the confirmation
2802 * request. The only exception is when we're dedicated bonding
2803 * initiators (connect_cfm_cb set) since then we always have the MITM
2804 * bit set. */
2805 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
2806 BT_DBG("Rejecting request: remote device can't provide MITM");
2807 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
2808 sizeof(ev->bdaddr), &ev->bdaddr);
2809 goto unlock;
2810 }
2811
2812 /* If no side requires MITM protection; auto-accept */
2813 if ((!loc_mitm || conn->remote_cap == 0x03) &&
2814 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002815
2816 /* If we're not the initiators request authorization to
2817 * proceed from user space (mgmt_user_confirm with
2818 * confirm_hint set to 1). */
2819 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
2820 BT_DBG("Confirming auto-accept as acceptor");
2821 confirm_hint = 1;
2822 goto confirm;
2823 }
2824
Johan Hedberg9f616562011-04-28 11:28:54 -07002825 BT_DBG("Auto-accept of user confirmation with %ums delay",
2826 hdev->auto_accept_delay);
2827
2828 if (hdev->auto_accept_delay > 0) {
2829 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
2830 mod_timer(&conn->auto_accept_timer, jiffies + delay);
2831 goto unlock;
2832 }
2833
Johan Hedberg7a828902011-04-28 11:28:53 -07002834 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
2835 sizeof(ev->bdaddr), &ev->bdaddr);
2836 goto unlock;
2837 }
2838
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002839confirm:
Johan Hedberg744cf192011-11-08 20:40:14 +02002840 mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002841 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07002842
2843unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03002844 hci_dev_unlock(hdev);
2845}
2846
Brian Gix1143d452011-11-23 08:28:34 -08002847static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
2848 struct sk_buff *skb)
2849{
2850 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
2851
2852 BT_DBG("%s", hdev->name);
2853
2854 hci_dev_lock(hdev);
2855
2856 if (test_bit(HCI_MGMT, &hdev->flags))
2857 mgmt_user_passkey_request(hdev, &ev->bdaddr);
2858
2859 hci_dev_unlock(hdev);
2860}
2861
Marcel Holtmann04936842008-07-14 20:13:48 +02002862static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2863{
2864 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
2865 struct hci_conn *conn;
2866
2867 BT_DBG("%s", hdev->name);
2868
2869 hci_dev_lock(hdev);
2870
2871 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03002872 if (!conn)
2873 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002874
Johan Hedberg2a611692011-02-19 12:06:00 -03002875 /* To avoid duplicate auth_failed events to user space we check
2876 * the HCI_CONN_AUTH_PEND flag which will be set if we
2877 * initiated the authentication. A traditional auth_complete
2878 * event gets always produced as initiator and is also mapped to
2879 * the mgmt_auth_failed event */
2880 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
Johan Hedberg744cf192011-11-08 20:40:14 +02002881 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03002882
2883 hci_conn_put(conn);
2884
2885unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002886 hci_dev_unlock(hdev);
2887}
2888
Marcel Holtmann41a96212008-07-14 20:13:48 +02002889static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2890{
2891 struct hci_ev_remote_host_features *ev = (void *) skb->data;
2892 struct inquiry_entry *ie;
2893
2894 BT_DBG("%s", hdev->name);
2895
2896 hci_dev_lock(hdev);
2897
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002898 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2899 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02002900 ie->data.ssp_mode = (ev->features[0] & 0x01);
2901
2902 hci_dev_unlock(hdev);
2903}
2904
Szymon Janc2763eda2011-03-22 13:12:22 +01002905static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
2906 struct sk_buff *skb)
2907{
2908 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
2909 struct oob_data *data;
2910
2911 BT_DBG("%s", hdev->name);
2912
2913 hci_dev_lock(hdev);
2914
Szymon Jance1ba1f12011-04-06 13:01:59 +02002915 if (!test_bit(HCI_MGMT, &hdev->flags))
2916 goto unlock;
2917
Szymon Janc2763eda2011-03-22 13:12:22 +01002918 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
2919 if (data) {
2920 struct hci_cp_remote_oob_data_reply cp;
2921
2922 bacpy(&cp.bdaddr, &ev->bdaddr);
2923 memcpy(cp.hash, data->hash, sizeof(cp.hash));
2924 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
2925
2926 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
2927 &cp);
2928 } else {
2929 struct hci_cp_remote_oob_data_neg_reply cp;
2930
2931 bacpy(&cp.bdaddr, &ev->bdaddr);
2932 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
2933 &cp);
2934 }
2935
Szymon Jance1ba1f12011-04-06 13:01:59 +02002936unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01002937 hci_dev_unlock(hdev);
2938}
2939
Ville Tervofcd89c02011-02-10 22:38:47 -03002940static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2941{
2942 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2943 struct hci_conn *conn;
2944
2945 BT_DBG("%s status %d", hdev->name, ev->status);
2946
2947 hci_dev_lock(hdev);
2948
2949 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03002950 if (!conn) {
2951 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
2952 if (!conn) {
2953 BT_ERR("No memory for new connection");
2954 hci_dev_unlock(hdev);
2955 return;
2956 }
Andre Guedes29b79882011-05-31 14:20:54 -03002957
2958 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03002959 }
Ville Tervofcd89c02011-02-10 22:38:47 -03002960
2961 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02002962 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
2963 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03002964 hci_proto_connect_cfm(conn, ev->status);
2965 conn->state = BT_CLOSED;
2966 hci_conn_del(conn);
2967 goto unlock;
2968 }
2969
Johan Hedberg48264f02011-11-09 13:58:58 +02002970 mgmt_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03002971
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03002972 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03002973 conn->handle = __le16_to_cpu(ev->handle);
2974 conn->state = BT_CONNECTED;
2975
2976 hci_conn_hold_device(conn);
2977 hci_conn_add_sysfs(conn);
2978
2979 hci_proto_connect_cfm(conn, ev->status);
2980
2981unlock:
2982 hci_dev_unlock(hdev);
2983}
2984
Andre Guedes9aa04c92011-05-26 16:23:51 -03002985static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
2986 struct sk_buff *skb)
2987{
Andre Guedese95beb42011-09-26 20:48:35 -03002988 u8 num_reports = skb->data[0];
2989 void *ptr = &skb->data[1];
Andre Guedes9aa04c92011-05-26 16:23:51 -03002990
2991 hci_dev_lock(hdev);
2992
Andre Guedese95beb42011-09-26 20:48:35 -03002993 while (num_reports--) {
2994 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03002995
Andre Guedes9aa04c92011-05-26 16:23:51 -03002996 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03002997
2998 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03002999 }
3000
3001 hci_dev_unlock(hdev);
3002}
3003
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003004static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3005 struct sk_buff *skb)
3006{
3007 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3008 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003009 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003010 struct hci_conn *conn;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003011 struct link_key *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003012
3013 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3014
3015 hci_dev_lock(hdev);
3016
3017 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003018 if (conn == NULL)
3019 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003020
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003021 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3022 if (ltk == NULL)
3023 goto not_found;
3024
3025 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003026 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes726b4ff2011-07-08 18:31:45 -03003027 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003028
3029 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3030
3031 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003032
3033 return;
3034
3035not_found:
3036 neg.handle = ev->handle;
3037 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3038 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003039}
3040
Ville Tervofcd89c02011-02-10 22:38:47 -03003041static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3042{
3043 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3044
3045 skb_pull(skb, sizeof(*le_ev));
3046
3047 switch (le_ev->subevent) {
3048 case HCI_EV_LE_CONN_COMPLETE:
3049 hci_le_conn_complete_evt(hdev, skb);
3050 break;
3051
Andre Guedes9aa04c92011-05-26 16:23:51 -03003052 case HCI_EV_LE_ADVERTISING_REPORT:
3053 hci_le_adv_report_evt(hdev, skb);
3054 break;
3055
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003056 case HCI_EV_LE_LTK_REQ:
3057 hci_le_ltk_request_evt(hdev, skb);
3058 break;
3059
Ville Tervofcd89c02011-02-10 22:38:47 -03003060 default:
3061 break;
3062 }
3063}
3064
Linus Torvalds1da177e2005-04-16 15:20:36 -07003065void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3066{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003067 struct hci_event_hdr *hdr = (void *) skb->data;
3068 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003069
3070 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3071
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003072 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003073 case HCI_EV_INQUIRY_COMPLETE:
3074 hci_inquiry_complete_evt(hdev, skb);
3075 break;
3076
3077 case HCI_EV_INQUIRY_RESULT:
3078 hci_inquiry_result_evt(hdev, skb);
3079 break;
3080
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003081 case HCI_EV_CONN_COMPLETE:
3082 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003083 break;
3084
Linus Torvalds1da177e2005-04-16 15:20:36 -07003085 case HCI_EV_CONN_REQUEST:
3086 hci_conn_request_evt(hdev, skb);
3087 break;
3088
Linus Torvalds1da177e2005-04-16 15:20:36 -07003089 case HCI_EV_DISCONN_COMPLETE:
3090 hci_disconn_complete_evt(hdev, skb);
3091 break;
3092
Linus Torvalds1da177e2005-04-16 15:20:36 -07003093 case HCI_EV_AUTH_COMPLETE:
3094 hci_auth_complete_evt(hdev, skb);
3095 break;
3096
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003097 case HCI_EV_REMOTE_NAME:
3098 hci_remote_name_evt(hdev, skb);
3099 break;
3100
Linus Torvalds1da177e2005-04-16 15:20:36 -07003101 case HCI_EV_ENCRYPT_CHANGE:
3102 hci_encrypt_change_evt(hdev, skb);
3103 break;
3104
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003105 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3106 hci_change_link_key_complete_evt(hdev, skb);
3107 break;
3108
3109 case HCI_EV_REMOTE_FEATURES:
3110 hci_remote_features_evt(hdev, skb);
3111 break;
3112
3113 case HCI_EV_REMOTE_VERSION:
3114 hci_remote_version_evt(hdev, skb);
3115 break;
3116
3117 case HCI_EV_QOS_SETUP_COMPLETE:
3118 hci_qos_setup_complete_evt(hdev, skb);
3119 break;
3120
3121 case HCI_EV_CMD_COMPLETE:
3122 hci_cmd_complete_evt(hdev, skb);
3123 break;
3124
3125 case HCI_EV_CMD_STATUS:
3126 hci_cmd_status_evt(hdev, skb);
3127 break;
3128
3129 case HCI_EV_ROLE_CHANGE:
3130 hci_role_change_evt(hdev, skb);
3131 break;
3132
3133 case HCI_EV_NUM_COMP_PKTS:
3134 hci_num_comp_pkts_evt(hdev, skb);
3135 break;
3136
3137 case HCI_EV_MODE_CHANGE:
3138 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003139 break;
3140
3141 case HCI_EV_PIN_CODE_REQ:
3142 hci_pin_code_request_evt(hdev, skb);
3143 break;
3144
3145 case HCI_EV_LINK_KEY_REQ:
3146 hci_link_key_request_evt(hdev, skb);
3147 break;
3148
3149 case HCI_EV_LINK_KEY_NOTIFY:
3150 hci_link_key_notify_evt(hdev, skb);
3151 break;
3152
3153 case HCI_EV_CLOCK_OFFSET:
3154 hci_clock_offset_evt(hdev, skb);
3155 break;
3156
Marcel Holtmanna8746412008-07-14 20:13:46 +02003157 case HCI_EV_PKT_TYPE_CHANGE:
3158 hci_pkt_type_change_evt(hdev, skb);
3159 break;
3160
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003161 case HCI_EV_PSCAN_REP_MODE:
3162 hci_pscan_rep_mode_evt(hdev, skb);
3163 break;
3164
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003165 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3166 hci_inquiry_result_with_rssi_evt(hdev, skb);
3167 break;
3168
3169 case HCI_EV_REMOTE_EXT_FEATURES:
3170 hci_remote_ext_features_evt(hdev, skb);
3171 break;
3172
3173 case HCI_EV_SYNC_CONN_COMPLETE:
3174 hci_sync_conn_complete_evt(hdev, skb);
3175 break;
3176
3177 case HCI_EV_SYNC_CONN_CHANGED:
3178 hci_sync_conn_changed_evt(hdev, skb);
3179 break;
3180
Marcel Holtmann04837f62006-07-03 10:02:33 +02003181 case HCI_EV_SNIFF_SUBRATE:
3182 hci_sniff_subrate_evt(hdev, skb);
3183 break;
3184
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003185 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3186 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003187 break;
3188
Marcel Holtmann04936842008-07-14 20:13:48 +02003189 case HCI_EV_IO_CAPA_REQUEST:
3190 hci_io_capa_request_evt(hdev, skb);
3191 break;
3192
Johan Hedberg03b555e2011-01-04 15:40:05 +02003193 case HCI_EV_IO_CAPA_REPLY:
3194 hci_io_capa_reply_evt(hdev, skb);
3195 break;
3196
Johan Hedberga5c29682011-02-19 12:05:57 -03003197 case HCI_EV_USER_CONFIRM_REQUEST:
3198 hci_user_confirm_request_evt(hdev, skb);
3199 break;
3200
Brian Gix1143d452011-11-23 08:28:34 -08003201 case HCI_EV_USER_PASSKEY_REQUEST:
3202 hci_user_passkey_request_evt(hdev, skb);
3203 break;
3204
Marcel Holtmann04936842008-07-14 20:13:48 +02003205 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3206 hci_simple_pair_complete_evt(hdev, skb);
3207 break;
3208
Marcel Holtmann41a96212008-07-14 20:13:48 +02003209 case HCI_EV_REMOTE_HOST_FEATURES:
3210 hci_remote_host_features_evt(hdev, skb);
3211 break;
3212
Ville Tervofcd89c02011-02-10 22:38:47 -03003213 case HCI_EV_LE_META:
3214 hci_le_meta_evt(hdev, skb);
3215 break;
3216
Szymon Janc2763eda2011-03-22 13:12:22 +01003217 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3218 hci_remote_oob_data_request_evt(hdev, skb);
3219 break;
3220
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003221 default:
3222 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003223 break;
3224 }
3225
3226 kfree_skb(skb);
3227 hdev->stat.evt_rx++;
3228}
3229
3230/* Generate internal stack event */
3231void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3232{
3233 struct hci_event_hdr *hdr;
3234 struct hci_ev_stack_internal *ev;
3235 struct sk_buff *skb;
3236
3237 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3238 if (!skb)
3239 return;
3240
3241 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3242 hdr->evt = HCI_EV_STACK_INTERNAL;
3243 hdr->plen = sizeof(*ev) + dlen;
3244
3245 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3246 ev->type = type;
3247 memcpy(ev->data, data, dlen);
3248
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003249 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003250 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003251
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003252 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003253 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003254 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003255 kfree_skb(skb);
3256}
Andre Guedese6100a22011-06-30 19:20:54 -03003257
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003258module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003259MODULE_PARM_DESC(enable_le, "Enable LE support");