blob: 48796832fdf098fd1e57452d6877a205761d51db [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
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200770static void hci_cc_read_data_block_size(struct hci_dev *hdev,
771 struct sk_buff *skb)
772{
773 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
774
775 BT_DBG("%s status 0x%x", hdev->name, rp->status);
776
777 if (rp->status)
778 return;
779
780 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
781 hdev->block_len = __le16_to_cpu(rp->block_len);
782 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
783
784 hdev->block_cnt = hdev->num_blocks;
785
786 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
787 hdev->block_cnt, hdev->block_len);
788
789 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
790}
791
Johan Hedberg23bb5762010-12-21 23:01:27 +0200792static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
793{
794 __u8 status = *((__u8 *) skb->data);
795
796 BT_DBG("%s status 0x%x", hdev->name, status);
797
798 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200799}
800
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300801static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
802 struct sk_buff *skb)
803{
804 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
805
806 BT_DBG("%s status 0x%x", hdev->name, rp->status);
807
808 if (rp->status)
809 return;
810
811 hdev->amp_status = rp->amp_status;
812 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
813 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
814 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
815 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
816 hdev->amp_type = rp->amp_type;
817 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
818 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
819 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
820 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
821
822 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
823}
824
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200825static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
826 struct sk_buff *skb)
827{
828 __u8 status = *((__u8 *) skb->data);
829
830 BT_DBG("%s status 0x%x", hdev->name, status);
831
832 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
833}
834
Johan Hedbergd5859e22011-01-25 01:19:58 +0200835static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
836{
837 __u8 status = *((__u8 *) skb->data);
838
839 BT_DBG("%s status 0x%x", hdev->name, status);
840
841 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
842}
843
844static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
845 struct sk_buff *skb)
846{
847 __u8 status = *((__u8 *) skb->data);
848
849 BT_DBG("%s status 0x%x", hdev->name, status);
850
851 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
852}
853
854static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
855 struct sk_buff *skb)
856{
857 __u8 status = *((__u8 *) skb->data);
858
859 BT_DBG("%s status 0x%x", hdev->name, status);
860
861 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
862}
863
864static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
865{
866 __u8 status = *((__u8 *) skb->data);
867
868 BT_DBG("%s status 0x%x", hdev->name, status);
869
870 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
871}
872
Johan Hedberg980e1a52011-01-22 06:10:07 +0200873static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
874{
875 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
876 struct hci_cp_pin_code_reply *cp;
877 struct hci_conn *conn;
878
879 BT_DBG("%s status 0x%x", hdev->name, rp->status);
880
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200881 hci_dev_lock(hdev);
882
Johan Hedberg980e1a52011-01-22 06:10:07 +0200883 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200884 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200885
886 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200887 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200888
889 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
890 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200891 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200892
893 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
894 if (conn)
895 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200896
897unlock:
898 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200899}
900
901static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
902{
903 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
904
905 BT_DBG("%s status 0x%x", hdev->name, rp->status);
906
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200907 hci_dev_lock(hdev);
908
Johan Hedberg980e1a52011-01-22 06:10:07 +0200909 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200910 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200911 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200912
913 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200914}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200915
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300916static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
917 struct sk_buff *skb)
918{
919 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
920
921 BT_DBG("%s status 0x%x", hdev->name, rp->status);
922
923 if (rp->status)
924 return;
925
926 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
927 hdev->le_pkts = rp->le_max_pkt;
928
929 hdev->le_cnt = hdev->le_pkts;
930
931 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
932
933 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
934}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200935
Johan Hedberga5c29682011-02-19 12:05:57 -0300936static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
937{
938 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
939
940 BT_DBG("%s status 0x%x", hdev->name, rp->status);
941
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200942 hci_dev_lock(hdev);
943
Johan Hedberga5c29682011-02-19 12:05:57 -0300944 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200945 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300946 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200947
948 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300949}
950
951static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
952 struct sk_buff *skb)
953{
954 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
955
956 BT_DBG("%s status 0x%x", hdev->name, rp->status);
957
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200958 hci_dev_lock(hdev);
959
Johan Hedberga5c29682011-02-19 12:05:57 -0300960 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200961 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300962 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200963
964 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300965}
966
Brian Gix1143d452011-11-23 08:28:34 -0800967static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
968{
969 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
970
971 BT_DBG("%s status 0x%x", hdev->name, rp->status);
972
973 hci_dev_lock(hdev);
974
975 if (test_bit(HCI_MGMT, &hdev->flags))
976 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr,
977 rp->status);
978
979 hci_dev_unlock(hdev);
980}
981
982static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
983 struct sk_buff *skb)
984{
985 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
986
987 BT_DBG("%s status 0x%x", hdev->name, rp->status);
988
989 hci_dev_lock(hdev);
990
991 if (test_bit(HCI_MGMT, &hdev->flags))
992 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
993 rp->status);
994
995 hci_dev_unlock(hdev);
996}
997
Szymon Jancc35938b2011-03-22 13:12:21 +0100998static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
999 struct sk_buff *skb)
1000{
1001 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1002
1003 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1004
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001005 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001006 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001007 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001008 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001009}
1010
Andre Guedes07f7fa52011-12-02 21:13:31 +09001011static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1012{
1013 __u8 status = *((__u8 *) skb->data);
1014
1015 BT_DBG("%s status 0x%x", hdev->name, status);
1016}
1017
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001018static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1019 struct sk_buff *skb)
1020{
1021 struct hci_cp_le_set_scan_enable *cp;
1022 __u8 status = *((__u8 *) skb->data);
1023
1024 BT_DBG("%s status 0x%x", hdev->name, status);
1025
1026 if (status)
1027 return;
1028
1029 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1030 if (!cp)
1031 return;
1032
Andre Guedes35815082011-05-26 16:23:53 -03001033 if (cp->enable == 0x01) {
Andre Guedesd23264a2011-11-25 20:53:38 -03001034 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1035
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001036 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001037
1038 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001039 hci_adv_entries_clear(hdev);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001040 hci_dev_unlock(hdev);
Andre Guedes35815082011-05-26 16:23:53 -03001041 } else if (cp->enable == 0x00) {
Andre Guedesd23264a2011-11-25 20:53:38 -03001042 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1043
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001044 cancel_delayed_work_sync(&hdev->adv_work);
1045 queue_delayed_work(hdev->workqueue, &hdev->adv_work,
1046 jiffies + ADV_CLEAR_TIMEOUT);
Andre Guedes35815082011-05-26 16:23:53 -03001047 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001048}
1049
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001050static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1051{
1052 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1053
1054 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1055
1056 if (rp->status)
1057 return;
1058
1059 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1060}
1061
1062static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1063{
1064 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1065
1066 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1067
1068 if (rp->status)
1069 return;
1070
1071 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1072}
1073
Andre Guedesf9b49302011-06-30 19:20:53 -03001074static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1075 struct sk_buff *skb)
1076{
1077 struct hci_cp_read_local_ext_features cp;
1078 __u8 status = *((__u8 *) skb->data);
1079
1080 BT_DBG("%s status 0x%x", hdev->name, status);
1081
1082 if (status)
1083 return;
1084
1085 cp.page = 0x01;
1086 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1087}
1088
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001089static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1090{
1091 BT_DBG("%s status 0x%x", hdev->name, status);
1092
1093 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001094 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001095 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001096 hci_dev_lock(hdev);
Johan Hedberg164a6e72011-11-01 17:06:44 +02001097 if (test_bit(HCI_MGMT, &hdev->flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001098 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001099 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001100 return;
1101 }
1102
Andre Guedes89352e72011-11-04 14:16:53 -03001103 set_bit(HCI_INQUIRY, &hdev->flags);
1104
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001105 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001106 mgmt_discovering(hdev, 1);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001107 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001108}
1109
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1111{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001112 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001115 BT_DBG("%s status 0x%x", hdev->name, status);
1116
1117 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 if (!cp)
1119 return;
1120
1121 hci_dev_lock(hdev);
1122
1123 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1124
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001125 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126
1127 if (status) {
1128 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001129 if (status != 0x0c || conn->attempt > 2) {
1130 conn->state = BT_CLOSED;
1131 hci_proto_connect_cfm(conn, status);
1132 hci_conn_del(conn);
1133 } else
1134 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 }
1136 } else {
1137 if (!conn) {
1138 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1139 if (conn) {
1140 conn->out = 1;
1141 conn->link_mode |= HCI_LM_MASTER;
1142 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001143 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 }
1145 }
1146
1147 hci_dev_unlock(hdev);
1148}
1149
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001150static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001152 struct hci_cp_add_sco *cp;
1153 struct hci_conn *acl, *sco;
1154 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001156 BT_DBG("%s status 0x%x", hdev->name, status);
1157
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001158 if (!status)
1159 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001161 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1162 if (!cp)
1163 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001165 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001167 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001168
1169 hci_dev_lock(hdev);
1170
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001171 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001172 if (acl) {
1173 sco = acl->link;
1174 if (sco) {
1175 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001176
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001177 hci_proto_connect_cfm(sco, status);
1178 hci_conn_del(sco);
1179 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001180 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001181
1182 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183}
1184
Marcel Holtmannf8558552008-07-14 20:13:49 +02001185static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1186{
1187 struct hci_cp_auth_requested *cp;
1188 struct hci_conn *conn;
1189
1190 BT_DBG("%s status 0x%x", hdev->name, status);
1191
1192 if (!status)
1193 return;
1194
1195 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1196 if (!cp)
1197 return;
1198
1199 hci_dev_lock(hdev);
1200
1201 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1202 if (conn) {
1203 if (conn->state == BT_CONFIG) {
1204 hci_proto_connect_cfm(conn, status);
1205 hci_conn_put(conn);
1206 }
1207 }
1208
1209 hci_dev_unlock(hdev);
1210}
1211
1212static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1213{
1214 struct hci_cp_set_conn_encrypt *cp;
1215 struct hci_conn *conn;
1216
1217 BT_DBG("%s status 0x%x", hdev->name, status);
1218
1219 if (!status)
1220 return;
1221
1222 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1223 if (!cp)
1224 return;
1225
1226 hci_dev_lock(hdev);
1227
1228 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1229 if (conn) {
1230 if (conn->state == BT_CONFIG) {
1231 hci_proto_connect_cfm(conn, status);
1232 hci_conn_put(conn);
1233 }
1234 }
1235
1236 hci_dev_unlock(hdev);
1237}
1238
Johan Hedberg127178d2010-11-18 22:22:29 +02001239static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001240 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001241{
Johan Hedberg392599b2010-11-18 22:22:28 +02001242 if (conn->state != BT_CONFIG || !conn->out)
1243 return 0;
1244
Johan Hedberg765c2a92011-01-19 12:06:52 +05301245 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001246 return 0;
1247
1248 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001249 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedberg392599b2010-11-18 22:22:28 +02001250 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001251 conn->pending_sec_level != BT_SECURITY_HIGH &&
1252 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001253 return 0;
1254
Johan Hedberg392599b2010-11-18 22:22:28 +02001255 return 1;
1256}
1257
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001258static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1259{
Johan Hedberg127178d2010-11-18 22:22:29 +02001260 struct hci_cp_remote_name_req *cp;
1261 struct hci_conn *conn;
1262
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001263 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001264
1265 /* If successful wait for the name req complete event before
1266 * checking for the need to do authentication */
1267 if (!status)
1268 return;
1269
1270 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1271 if (!cp)
1272 return;
1273
1274 hci_dev_lock(hdev);
1275
1276 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001277 if (!conn)
1278 goto unlock;
1279
1280 if (!hci_outgoing_auth_needed(hdev, conn))
1281 goto unlock;
1282
1283 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001284 struct hci_cp_auth_requested cp;
1285 cp.handle = __cpu_to_le16(conn->handle);
1286 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1287 }
1288
Johan Hedberg79c6c702011-04-28 11:28:55 -07001289unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001290 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001291}
1292
Marcel Holtmann769be972008-07-14 20:13:49 +02001293static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1294{
1295 struct hci_cp_read_remote_features *cp;
1296 struct hci_conn *conn;
1297
1298 BT_DBG("%s status 0x%x", hdev->name, status);
1299
1300 if (!status)
1301 return;
1302
1303 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1304 if (!cp)
1305 return;
1306
1307 hci_dev_lock(hdev);
1308
1309 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1310 if (conn) {
1311 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001312 hci_proto_connect_cfm(conn, status);
1313 hci_conn_put(conn);
1314 }
1315 }
1316
1317 hci_dev_unlock(hdev);
1318}
1319
1320static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1321{
1322 struct hci_cp_read_remote_ext_features *cp;
1323 struct hci_conn *conn;
1324
1325 BT_DBG("%s status 0x%x", hdev->name, status);
1326
1327 if (!status)
1328 return;
1329
1330 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1331 if (!cp)
1332 return;
1333
1334 hci_dev_lock(hdev);
1335
1336 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1337 if (conn) {
1338 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001339 hci_proto_connect_cfm(conn, status);
1340 hci_conn_put(conn);
1341 }
1342 }
1343
1344 hci_dev_unlock(hdev);
1345}
1346
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001347static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1348{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001349 struct hci_cp_setup_sync_conn *cp;
1350 struct hci_conn *acl, *sco;
1351 __u16 handle;
1352
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001353 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001354
1355 if (!status)
1356 return;
1357
1358 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1359 if (!cp)
1360 return;
1361
1362 handle = __le16_to_cpu(cp->handle);
1363
1364 BT_DBG("%s handle %d", hdev->name, handle);
1365
1366 hci_dev_lock(hdev);
1367
1368 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001369 if (acl) {
1370 sco = acl->link;
1371 if (sco) {
1372 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001373
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001374 hci_proto_connect_cfm(sco, status);
1375 hci_conn_del(sco);
1376 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001377 }
1378
1379 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001380}
1381
1382static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1383{
1384 struct hci_cp_sniff_mode *cp;
1385 struct hci_conn *conn;
1386
1387 BT_DBG("%s status 0x%x", hdev->name, status);
1388
1389 if (!status)
1390 return;
1391
1392 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1393 if (!cp)
1394 return;
1395
1396 hci_dev_lock(hdev);
1397
1398 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001399 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001400 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1401
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001402 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1403 hci_sco_setup(conn, status);
1404 }
1405
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001406 hci_dev_unlock(hdev);
1407}
1408
1409static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1410{
1411 struct hci_cp_exit_sniff_mode *cp;
1412 struct hci_conn *conn;
1413
1414 BT_DBG("%s status 0x%x", hdev->name, status);
1415
1416 if (!status)
1417 return;
1418
1419 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1420 if (!cp)
1421 return;
1422
1423 hci_dev_lock(hdev);
1424
1425 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001426 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001427 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1428
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001429 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1430 hci_sco_setup(conn, status);
1431 }
1432
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001433 hci_dev_unlock(hdev);
1434}
1435
Ville Tervofcd89c02011-02-10 22:38:47 -03001436static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1437{
1438 struct hci_cp_le_create_conn *cp;
1439 struct hci_conn *conn;
1440
1441 BT_DBG("%s status 0x%x", hdev->name, status);
1442
1443 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1444 if (!cp)
1445 return;
1446
1447 hci_dev_lock(hdev);
1448
1449 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1450
1451 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1452 conn);
1453
1454 if (status) {
1455 if (conn && conn->state == BT_CONNECT) {
1456 conn->state = BT_CLOSED;
1457 hci_proto_connect_cfm(conn, status);
1458 hci_conn_del(conn);
1459 }
1460 } else {
1461 if (!conn) {
1462 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001463 if (conn) {
1464 conn->dst_type = cp->peer_addr_type;
Ville Tervofcd89c02011-02-10 22:38:47 -03001465 conn->out = 1;
Andre Guedes29b79882011-05-31 14:20:54 -03001466 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001467 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001468 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001469 }
1470 }
1471
1472 hci_dev_unlock(hdev);
1473}
1474
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001475static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1476{
1477 BT_DBG("%s status 0x%x", hdev->name, status);
1478}
1479
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001480static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1481{
1482 __u8 status = *((__u8 *) skb->data);
1483
1484 BT_DBG("%s status %d", hdev->name, status);
1485
Johan Hedberg23bb5762010-12-21 23:01:27 +02001486 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001487
1488 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001489
1490 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1491 return;
1492
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001493 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001494 mgmt_discovering(hdev, 0);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001495 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001496}
1497
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1499{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001500 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001501 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 int num_rsp = *((__u8 *) skb->data);
1503
1504 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1505
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001506 if (!num_rsp)
1507 return;
1508
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001510
Johan Hedberge17acd42011-03-30 23:57:16 +03001511 for (; num_rsp; num_rsp--, info++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512 bacpy(&data.bdaddr, &info->bdaddr);
1513 data.pscan_rep_mode = info->pscan_rep_mode;
1514 data.pscan_period_mode = info->pscan_period_mode;
1515 data.pscan_mode = info->pscan_mode;
1516 memcpy(data.dev_class, info->dev_class, 3);
1517 data.clock_offset = info->clock_offset;
1518 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001519 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02001521 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg4c659c32011-11-07 23:13:39 +02001522 info->dev_class, 0, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001524
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 hci_dev_unlock(hdev);
1526}
1527
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001528static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001530 struct hci_ev_conn_complete *ev = (void *) skb->data;
1531 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001533 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001534
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001536
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001537 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001538 if (!conn) {
1539 if (ev->link_type != SCO_LINK)
1540 goto unlock;
1541
1542 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1543 if (!conn)
1544 goto unlock;
1545
1546 conn->type = SCO_LINK;
1547 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001548
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001549 if (!ev->status) {
1550 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001551
1552 if (conn->type == ACL_LINK) {
1553 conn->state = BT_CONFIG;
1554 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001555 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg48264f02011-11-09 13:58:58 +02001556 mgmt_connected(hdev, &ev->bdaddr, conn->type,
1557 conn->dst_type);
Marcel Holtmann769be972008-07-14 20:13:49 +02001558 } else
1559 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001560
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001561 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001562 hci_conn_add_sysfs(conn);
1563
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001564 if (test_bit(HCI_AUTH, &hdev->flags))
1565 conn->link_mode |= HCI_LM_AUTH;
1566
1567 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1568 conn->link_mode |= HCI_LM_ENCRYPT;
1569
1570 /* Get remote features */
1571 if (conn->type == ACL_LINK) {
1572 struct hci_cp_read_remote_features cp;
1573 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001574 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1575 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001576 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001577
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001578 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001579 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001580 struct hci_cp_change_conn_ptype cp;
1581 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001582 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1583 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1584 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001585 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001586 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001587 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001588 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001589 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001590 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001591 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001592
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001593 if (conn->type == ACL_LINK)
1594 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001595
Marcel Holtmann769be972008-07-14 20:13:49 +02001596 if (ev->status) {
1597 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001598 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001599 } else if (ev->link_type != ACL_LINK)
1600 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001601
1602unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001604
1605 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606}
1607
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1609{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001610 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 int mask = hdev->link_mode;
1612
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001613 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1614 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615
1616 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1617
Szymon Janc138d22e2011-02-17 16:44:23 +01001618 if ((mask & HCI_LM_ACCEPT) &&
1619 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001621 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623
1624 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001625
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001626 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1627 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001628 memcpy(ie->data.dev_class, ev->dev_class, 3);
1629
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1631 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001632 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1633 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001634 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635 hci_dev_unlock(hdev);
1636 return;
1637 }
1638 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001639
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 memcpy(conn->dev_class, ev->dev_class, 3);
1641 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001642
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643 hci_dev_unlock(hdev);
1644
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001645 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1646 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001648 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001650 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1651 cp.role = 0x00; /* Become master */
1652 else
1653 cp.role = 0x01; /* Remain slave */
1654
1655 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1656 sizeof(cp), &cp);
1657 } else {
1658 struct hci_cp_accept_sync_conn_req cp;
1659
1660 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001661 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001662
1663 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1664 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1665 cp.max_latency = cpu_to_le16(0xffff);
1666 cp.content_format = cpu_to_le16(hdev->voice_setting);
1667 cp.retrans_effort = 0xff;
1668
1669 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1670 sizeof(cp), &cp);
1671 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 } else {
1673 /* Connection rejected */
1674 struct hci_cp_reject_conn_req cp;
1675
1676 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001677 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001678 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 }
1680}
1681
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1683{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001684 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001685 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686
1687 BT_DBG("%s status %d", hdev->name, ev->status);
1688
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 hci_dev_lock(hdev);
1690
Marcel Holtmann04837f62006-07-03 10:02:33 +02001691 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001692 if (!conn)
1693 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001694
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001695 if (ev->status == 0)
1696 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001698 if (conn->type == ACL_LINK || conn->type == LE_LINK) {
1699 if (ev->status != 0)
1700 mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
1701 else
1702 mgmt_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001703 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001704 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001705
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001706 if (ev->status == 0) {
1707 hci_proto_disconn_cfm(conn, ev->reason);
1708 hci_conn_del(conn);
1709 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001710
1711unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 hci_dev_unlock(hdev);
1713}
1714
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001715static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1716{
1717 struct hci_ev_auth_complete *ev = (void *) skb->data;
1718 struct hci_conn *conn;
1719
1720 BT_DBG("%s status %d", hdev->name, ev->status);
1721
1722 hci_dev_lock(hdev);
1723
1724 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001725 if (!conn)
1726 goto unlock;
1727
1728 if (!ev->status) {
1729 if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) &&
1730 test_bit(HCI_CONN_REAUTH_PEND, &conn->pend)) {
1731 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001732 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001733 conn->link_mode |= HCI_LM_AUTH;
1734 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001735 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001736 } else {
Johan Hedberg744cf192011-11-08 20:40:14 +02001737 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001738 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001739
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001740 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1741 clear_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001742
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001743 if (conn->state == BT_CONFIG) {
1744 if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) {
1745 struct hci_cp_set_conn_encrypt cp;
1746 cp.handle = ev->handle;
1747 cp.encrypt = 0x01;
1748 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1749 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001750 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001751 conn->state = BT_CONNECTED;
1752 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001753 hci_conn_put(conn);
1754 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001755 } else {
1756 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001757
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001758 hci_conn_hold(conn);
1759 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1760 hci_conn_put(conn);
1761 }
1762
1763 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1764 if (!ev->status) {
1765 struct hci_cp_set_conn_encrypt cp;
1766 cp.handle = ev->handle;
1767 cp.encrypt = 0x01;
1768 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1769 &cp);
1770 } else {
1771 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1772 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001773 }
1774 }
1775
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001776unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001777 hci_dev_unlock(hdev);
1778}
1779
1780static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1781{
Johan Hedberg127178d2010-11-18 22:22:29 +02001782 struct hci_ev_remote_name *ev = (void *) skb->data;
1783 struct hci_conn *conn;
1784
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001785 BT_DBG("%s", hdev->name);
1786
1787 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001788
1789 hci_dev_lock(hdev);
1790
Johan Hedberga88a9652011-03-30 13:18:12 +03001791 if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001792 mgmt_remote_name(hdev, &ev->bdaddr, ev->name);
Johan Hedberga88a9652011-03-30 13:18:12 +03001793
Johan Hedberg127178d2010-11-18 22:22:29 +02001794 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001795 if (!conn)
1796 goto unlock;
1797
1798 if (!hci_outgoing_auth_needed(hdev, conn))
1799 goto unlock;
1800
1801 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001802 struct hci_cp_auth_requested cp;
1803 cp.handle = __cpu_to_le16(conn->handle);
1804 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1805 }
1806
Johan Hedberg79c6c702011-04-28 11:28:55 -07001807unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001808 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001809}
1810
1811static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1812{
1813 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1814 struct hci_conn *conn;
1815
1816 BT_DBG("%s status %d", hdev->name, ev->status);
1817
1818 hci_dev_lock(hdev);
1819
1820 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1821 if (conn) {
1822 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001823 if (ev->encrypt) {
1824 /* Encryption implies authentication */
1825 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001826 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001827 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001828 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001829 conn->link_mode &= ~HCI_LM_ENCRYPT;
1830 }
1831
1832 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1833
Marcel Holtmannf8558552008-07-14 20:13:49 +02001834 if (conn->state == BT_CONFIG) {
1835 if (!ev->status)
1836 conn->state = BT_CONNECTED;
1837
1838 hci_proto_connect_cfm(conn, ev->status);
1839 hci_conn_put(conn);
1840 } else
1841 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001842 }
1843
1844 hci_dev_unlock(hdev);
1845}
1846
1847static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1848{
1849 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1850 struct hci_conn *conn;
1851
1852 BT_DBG("%s status %d", hdev->name, ev->status);
1853
1854 hci_dev_lock(hdev);
1855
1856 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1857 if (conn) {
1858 if (!ev->status)
1859 conn->link_mode |= HCI_LM_SECURE;
1860
1861 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1862
1863 hci_key_change_cfm(conn, ev->status);
1864 }
1865
1866 hci_dev_unlock(hdev);
1867}
1868
1869static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1870{
1871 struct hci_ev_remote_features *ev = (void *) skb->data;
1872 struct hci_conn *conn;
1873
1874 BT_DBG("%s status %d", hdev->name, ev->status);
1875
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001876 hci_dev_lock(hdev);
1877
1878 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001879 if (!conn)
1880 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001881
Johan Hedbergccd556f2010-11-10 17:11:51 +02001882 if (!ev->status)
1883 memcpy(conn->features, ev->features, 8);
1884
1885 if (conn->state != BT_CONFIG)
1886 goto unlock;
1887
1888 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1889 struct hci_cp_read_remote_ext_features cp;
1890 cp.handle = ev->handle;
1891 cp.page = 0x01;
1892 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001893 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001894 goto unlock;
1895 }
1896
Johan Hedberg127178d2010-11-18 22:22:29 +02001897 if (!ev->status) {
1898 struct hci_cp_remote_name_req cp;
1899 memset(&cp, 0, sizeof(cp));
1900 bacpy(&cp.bdaddr, &conn->dst);
1901 cp.pscan_rep_mode = 0x02;
1902 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1903 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001904
Johan Hedberg127178d2010-11-18 22:22:29 +02001905 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001906 conn->state = BT_CONNECTED;
1907 hci_proto_connect_cfm(conn, ev->status);
1908 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001909 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001910
Johan Hedbergccd556f2010-11-10 17:11:51 +02001911unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001912 hci_dev_unlock(hdev);
1913}
1914
1915static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1916{
1917 BT_DBG("%s", hdev->name);
1918}
1919
1920static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1921{
1922 BT_DBG("%s", hdev->name);
1923}
1924
1925static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1926{
1927 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1928 __u16 opcode;
1929
1930 skb_pull(skb, sizeof(*ev));
1931
1932 opcode = __le16_to_cpu(ev->opcode);
1933
1934 switch (opcode) {
1935 case HCI_OP_INQUIRY_CANCEL:
1936 hci_cc_inquiry_cancel(hdev, skb);
1937 break;
1938
1939 case HCI_OP_EXIT_PERIODIC_INQ:
1940 hci_cc_exit_periodic_inq(hdev, skb);
1941 break;
1942
1943 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1944 hci_cc_remote_name_req_cancel(hdev, skb);
1945 break;
1946
1947 case HCI_OP_ROLE_DISCOVERY:
1948 hci_cc_role_discovery(hdev, skb);
1949 break;
1950
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001951 case HCI_OP_READ_LINK_POLICY:
1952 hci_cc_read_link_policy(hdev, skb);
1953 break;
1954
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001955 case HCI_OP_WRITE_LINK_POLICY:
1956 hci_cc_write_link_policy(hdev, skb);
1957 break;
1958
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001959 case HCI_OP_READ_DEF_LINK_POLICY:
1960 hci_cc_read_def_link_policy(hdev, skb);
1961 break;
1962
1963 case HCI_OP_WRITE_DEF_LINK_POLICY:
1964 hci_cc_write_def_link_policy(hdev, skb);
1965 break;
1966
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001967 case HCI_OP_RESET:
1968 hci_cc_reset(hdev, skb);
1969 break;
1970
1971 case HCI_OP_WRITE_LOCAL_NAME:
1972 hci_cc_write_local_name(hdev, skb);
1973 break;
1974
1975 case HCI_OP_READ_LOCAL_NAME:
1976 hci_cc_read_local_name(hdev, skb);
1977 break;
1978
1979 case HCI_OP_WRITE_AUTH_ENABLE:
1980 hci_cc_write_auth_enable(hdev, skb);
1981 break;
1982
1983 case HCI_OP_WRITE_ENCRYPT_MODE:
1984 hci_cc_write_encrypt_mode(hdev, skb);
1985 break;
1986
1987 case HCI_OP_WRITE_SCAN_ENABLE:
1988 hci_cc_write_scan_enable(hdev, skb);
1989 break;
1990
1991 case HCI_OP_READ_CLASS_OF_DEV:
1992 hci_cc_read_class_of_dev(hdev, skb);
1993 break;
1994
1995 case HCI_OP_WRITE_CLASS_OF_DEV:
1996 hci_cc_write_class_of_dev(hdev, skb);
1997 break;
1998
1999 case HCI_OP_READ_VOICE_SETTING:
2000 hci_cc_read_voice_setting(hdev, skb);
2001 break;
2002
2003 case HCI_OP_WRITE_VOICE_SETTING:
2004 hci_cc_write_voice_setting(hdev, skb);
2005 break;
2006
2007 case HCI_OP_HOST_BUFFER_SIZE:
2008 hci_cc_host_buffer_size(hdev, skb);
2009 break;
2010
Marcel Holtmann333140b2008-07-14 20:13:48 +02002011 case HCI_OP_READ_SSP_MODE:
2012 hci_cc_read_ssp_mode(hdev, skb);
2013 break;
2014
2015 case HCI_OP_WRITE_SSP_MODE:
2016 hci_cc_write_ssp_mode(hdev, skb);
2017 break;
2018
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002019 case HCI_OP_READ_LOCAL_VERSION:
2020 hci_cc_read_local_version(hdev, skb);
2021 break;
2022
2023 case HCI_OP_READ_LOCAL_COMMANDS:
2024 hci_cc_read_local_commands(hdev, skb);
2025 break;
2026
2027 case HCI_OP_READ_LOCAL_FEATURES:
2028 hci_cc_read_local_features(hdev, skb);
2029 break;
2030
Andre Guedes971e3a42011-06-30 19:20:52 -03002031 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2032 hci_cc_read_local_ext_features(hdev, skb);
2033 break;
2034
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002035 case HCI_OP_READ_BUFFER_SIZE:
2036 hci_cc_read_buffer_size(hdev, skb);
2037 break;
2038
2039 case HCI_OP_READ_BD_ADDR:
2040 hci_cc_read_bd_addr(hdev, skb);
2041 break;
2042
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002043 case HCI_OP_READ_DATA_BLOCK_SIZE:
2044 hci_cc_read_data_block_size(hdev, skb);
2045 break;
2046
Johan Hedberg23bb5762010-12-21 23:01:27 +02002047 case HCI_OP_WRITE_CA_TIMEOUT:
2048 hci_cc_write_ca_timeout(hdev, skb);
2049 break;
2050
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002051 case HCI_OP_READ_FLOW_CONTROL_MODE:
2052 hci_cc_read_flow_control_mode(hdev, skb);
2053 break;
2054
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002055 case HCI_OP_READ_LOCAL_AMP_INFO:
2056 hci_cc_read_local_amp_info(hdev, skb);
2057 break;
2058
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002059 case HCI_OP_DELETE_STORED_LINK_KEY:
2060 hci_cc_delete_stored_link_key(hdev, skb);
2061 break;
2062
Johan Hedbergd5859e22011-01-25 01:19:58 +02002063 case HCI_OP_SET_EVENT_MASK:
2064 hci_cc_set_event_mask(hdev, skb);
2065 break;
2066
2067 case HCI_OP_WRITE_INQUIRY_MODE:
2068 hci_cc_write_inquiry_mode(hdev, skb);
2069 break;
2070
2071 case HCI_OP_READ_INQ_RSP_TX_POWER:
2072 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2073 break;
2074
2075 case HCI_OP_SET_EVENT_FLT:
2076 hci_cc_set_event_flt(hdev, skb);
2077 break;
2078
Johan Hedberg980e1a52011-01-22 06:10:07 +02002079 case HCI_OP_PIN_CODE_REPLY:
2080 hci_cc_pin_code_reply(hdev, skb);
2081 break;
2082
2083 case HCI_OP_PIN_CODE_NEG_REPLY:
2084 hci_cc_pin_code_neg_reply(hdev, skb);
2085 break;
2086
Szymon Jancc35938b2011-03-22 13:12:21 +01002087 case HCI_OP_READ_LOCAL_OOB_DATA:
2088 hci_cc_read_local_oob_data_reply(hdev, skb);
2089 break;
2090
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002091 case HCI_OP_LE_READ_BUFFER_SIZE:
2092 hci_cc_le_read_buffer_size(hdev, skb);
2093 break;
2094
Johan Hedberga5c29682011-02-19 12:05:57 -03002095 case HCI_OP_USER_CONFIRM_REPLY:
2096 hci_cc_user_confirm_reply(hdev, skb);
2097 break;
2098
2099 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2100 hci_cc_user_confirm_neg_reply(hdev, skb);
2101 break;
2102
Brian Gix1143d452011-11-23 08:28:34 -08002103 case HCI_OP_USER_PASSKEY_REPLY:
2104 hci_cc_user_passkey_reply(hdev, skb);
2105 break;
2106
2107 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2108 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002109
2110 case HCI_OP_LE_SET_SCAN_PARAM:
2111 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002112 break;
2113
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002114 case HCI_OP_LE_SET_SCAN_ENABLE:
2115 hci_cc_le_set_scan_enable(hdev, skb);
2116 break;
2117
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002118 case HCI_OP_LE_LTK_REPLY:
2119 hci_cc_le_ltk_reply(hdev, skb);
2120 break;
2121
2122 case HCI_OP_LE_LTK_NEG_REPLY:
2123 hci_cc_le_ltk_neg_reply(hdev, skb);
2124 break;
2125
Andre Guedesf9b49302011-06-30 19:20:53 -03002126 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2127 hci_cc_write_le_host_supported(hdev, skb);
2128 break;
2129
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002130 default:
2131 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2132 break;
2133 }
2134
Ville Tervo6bd32322011-02-16 16:32:41 +02002135 if (ev->opcode != HCI_OP_NOP)
2136 del_timer(&hdev->cmd_timer);
2137
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002138 if (ev->ncmd) {
2139 atomic_set(&hdev->cmd_cnt, 1);
2140 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002141 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002142 }
2143}
2144
2145static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2146{
2147 struct hci_ev_cmd_status *ev = (void *) skb->data;
2148 __u16 opcode;
2149
2150 skb_pull(skb, sizeof(*ev));
2151
2152 opcode = __le16_to_cpu(ev->opcode);
2153
2154 switch (opcode) {
2155 case HCI_OP_INQUIRY:
2156 hci_cs_inquiry(hdev, ev->status);
2157 break;
2158
2159 case HCI_OP_CREATE_CONN:
2160 hci_cs_create_conn(hdev, ev->status);
2161 break;
2162
2163 case HCI_OP_ADD_SCO:
2164 hci_cs_add_sco(hdev, ev->status);
2165 break;
2166
Marcel Holtmannf8558552008-07-14 20:13:49 +02002167 case HCI_OP_AUTH_REQUESTED:
2168 hci_cs_auth_requested(hdev, ev->status);
2169 break;
2170
2171 case HCI_OP_SET_CONN_ENCRYPT:
2172 hci_cs_set_conn_encrypt(hdev, ev->status);
2173 break;
2174
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002175 case HCI_OP_REMOTE_NAME_REQ:
2176 hci_cs_remote_name_req(hdev, ev->status);
2177 break;
2178
Marcel Holtmann769be972008-07-14 20:13:49 +02002179 case HCI_OP_READ_REMOTE_FEATURES:
2180 hci_cs_read_remote_features(hdev, ev->status);
2181 break;
2182
2183 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2184 hci_cs_read_remote_ext_features(hdev, ev->status);
2185 break;
2186
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002187 case HCI_OP_SETUP_SYNC_CONN:
2188 hci_cs_setup_sync_conn(hdev, ev->status);
2189 break;
2190
2191 case HCI_OP_SNIFF_MODE:
2192 hci_cs_sniff_mode(hdev, ev->status);
2193 break;
2194
2195 case HCI_OP_EXIT_SNIFF_MODE:
2196 hci_cs_exit_sniff_mode(hdev, ev->status);
2197 break;
2198
Johan Hedberg8962ee72011-01-20 12:40:27 +02002199 case HCI_OP_DISCONNECT:
2200 if (ev->status != 0)
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002201 mgmt_disconnect_failed(hdev, NULL, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002202 break;
2203
Ville Tervofcd89c02011-02-10 22:38:47 -03002204 case HCI_OP_LE_CREATE_CONN:
2205 hci_cs_le_create_conn(hdev, ev->status);
2206 break;
2207
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002208 case HCI_OP_LE_START_ENC:
2209 hci_cs_le_start_enc(hdev, ev->status);
2210 break;
2211
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002212 default:
2213 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2214 break;
2215 }
2216
Ville Tervo6bd32322011-02-16 16:32:41 +02002217 if (ev->opcode != HCI_OP_NOP)
2218 del_timer(&hdev->cmd_timer);
2219
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002220 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002221 atomic_set(&hdev->cmd_cnt, 1);
2222 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002223 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002224 }
2225}
2226
2227static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2228{
2229 struct hci_ev_role_change *ev = (void *) skb->data;
2230 struct hci_conn *conn;
2231
2232 BT_DBG("%s status %d", hdev->name, ev->status);
2233
2234 hci_dev_lock(hdev);
2235
2236 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2237 if (conn) {
2238 if (!ev->status) {
2239 if (ev->role)
2240 conn->link_mode &= ~HCI_LM_MASTER;
2241 else
2242 conn->link_mode |= HCI_LM_MASTER;
2243 }
2244
2245 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
2246
2247 hci_role_switch_cfm(conn, ev->status, ev->role);
2248 }
2249
2250 hci_dev_unlock(hdev);
2251}
2252
Linus Torvalds1da177e2005-04-16 15:20:36 -07002253static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2254{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002255 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002256 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 int i;
2258
2259 skb_pull(skb, sizeof(*ev));
2260
2261 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2262
2263 if (skb->len < ev->num_hndl * 4) {
2264 BT_DBG("%s bad parameters", hdev->name);
2265 return;
2266 }
2267
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002268 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269 struct hci_conn *conn;
2270 __u16 handle, count;
2271
Harvey Harrison83985312008-05-02 16:25:46 -07002272 handle = get_unaligned_le16(ptr++);
2273 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002274
2275 conn = hci_conn_hash_lookup_handle(hdev, handle);
2276 if (conn) {
2277 conn->sent -= count;
2278
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002279 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002280 hdev->acl_cnt += count;
2281 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002282 hdev->acl_cnt = hdev->acl_pkts;
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002283 } else if (conn->type == LE_LINK) {
2284 if (hdev->le_pkts) {
2285 hdev->le_cnt += count;
2286 if (hdev->le_cnt > hdev->le_pkts)
2287 hdev->le_cnt = hdev->le_pkts;
2288 } else {
2289 hdev->acl_cnt += count;
2290 if (hdev->acl_cnt > hdev->acl_pkts)
2291 hdev->acl_cnt = hdev->acl_pkts;
2292 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002293 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002294 hdev->sco_cnt += count;
2295 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002296 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297 }
2298 }
2299 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002300
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002301 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302}
2303
Marcel Holtmann04837f62006-07-03 10:02:33 +02002304static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002306 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002307 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308
2309 BT_DBG("%s status %d", hdev->name, ev->status);
2310
2311 hci_dev_lock(hdev);
2312
Marcel Holtmann04837f62006-07-03 10:02:33 +02002313 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2314 if (conn) {
2315 conn->mode = ev->mode;
2316 conn->interval = __le16_to_cpu(ev->interval);
2317
2318 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
2319 if (conn->mode == HCI_CM_ACTIVE)
2320 conn->power_save = 1;
2321 else
2322 conn->power_save = 0;
2323 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002324
2325 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
2326 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002327 }
2328
2329 hci_dev_unlock(hdev);
2330}
2331
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2333{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002334 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2335 struct hci_conn *conn;
2336
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002337 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002338
2339 hci_dev_lock(hdev);
2340
2341 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002342 if (!conn)
2343 goto unlock;
2344
2345 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002346 hci_conn_hold(conn);
2347 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2348 hci_conn_put(conn);
2349 }
2350
Johan Hedberg03b555e2011-01-04 15:40:05 +02002351 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
2352 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2353 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg582fbe92011-04-28 11:28:58 -07002354 else if (test_bit(HCI_MGMT, &hdev->flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002355 u8 secure;
2356
2357 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2358 secure = 1;
2359 else
2360 secure = 0;
2361
Johan Hedberg744cf192011-11-08 20:40:14 +02002362 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002363 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002364
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002365unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002366 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002367}
2368
Linus Torvalds1da177e2005-04-16 15:20:36 -07002369static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2370{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002371 struct hci_ev_link_key_req *ev = (void *) skb->data;
2372 struct hci_cp_link_key_reply cp;
2373 struct hci_conn *conn;
2374 struct link_key *key;
2375
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002376 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002377
2378 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
2379 return;
2380
2381 hci_dev_lock(hdev);
2382
2383 key = hci_find_link_key(hdev, &ev->bdaddr);
2384 if (!key) {
2385 BT_DBG("%s link key not found for %s", hdev->name,
2386 batostr(&ev->bdaddr));
2387 goto not_found;
2388 }
2389
2390 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2391 batostr(&ev->bdaddr));
2392
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002393 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) &&
2394 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002395 BT_DBG("%s ignoring debug key", hdev->name);
2396 goto not_found;
2397 }
2398
2399 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002400 if (conn) {
2401 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2402 conn->auth_type != 0xff &&
2403 (conn->auth_type & 0x01)) {
2404 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2405 goto not_found;
2406 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002407
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002408 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2409 conn->pending_sec_level == BT_SECURITY_HIGH) {
2410 BT_DBG("%s ignoring key unauthenticated for high \
2411 security", hdev->name);
2412 goto not_found;
2413 }
2414
2415 conn->key_type = key->type;
2416 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002417 }
2418
2419 bacpy(&cp.bdaddr, &ev->bdaddr);
2420 memcpy(cp.link_key, key->val, 16);
2421
2422 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2423
2424 hci_dev_unlock(hdev);
2425
2426 return;
2427
2428not_found:
2429 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2430 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002431}
2432
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2434{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002435 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2436 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002437 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002438
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002439 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002440
2441 hci_dev_lock(hdev);
2442
2443 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2444 if (conn) {
2445 hci_conn_hold(conn);
2446 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002447 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002448
2449 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2450 conn->key_type = ev->key_type;
2451
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002452 hci_conn_put(conn);
2453 }
2454
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002455 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002456 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002457 ev->key_type, pin_len);
2458
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002459 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460}
2461
Marcel Holtmann04837f62006-07-03 10:02:33 +02002462static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2463{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002464 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002465 struct hci_conn *conn;
2466
2467 BT_DBG("%s status %d", hdev->name, ev->status);
2468
2469 hci_dev_lock(hdev);
2470
2471 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002472 if (conn && !ev->status) {
2473 struct inquiry_entry *ie;
2474
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002475 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2476 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002477 ie->data.clock_offset = ev->clock_offset;
2478 ie->timestamp = jiffies;
2479 }
2480 }
2481
2482 hci_dev_unlock(hdev);
2483}
2484
Marcel Holtmanna8746412008-07-14 20:13:46 +02002485static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2486{
2487 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2488 struct hci_conn *conn;
2489
2490 BT_DBG("%s status %d", hdev->name, ev->status);
2491
2492 hci_dev_lock(hdev);
2493
2494 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2495 if (conn && !ev->status)
2496 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2497
2498 hci_dev_unlock(hdev);
2499}
2500
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002501static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2502{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002503 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002504 struct inquiry_entry *ie;
2505
2506 BT_DBG("%s", hdev->name);
2507
2508 hci_dev_lock(hdev);
2509
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002510 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2511 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002512 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2513 ie->timestamp = jiffies;
2514 }
2515
2516 hci_dev_unlock(hdev);
2517}
2518
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002519static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2520{
2521 struct inquiry_data data;
2522 int num_rsp = *((__u8 *) skb->data);
2523
2524 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2525
2526 if (!num_rsp)
2527 return;
2528
2529 hci_dev_lock(hdev);
2530
2531 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002532 struct inquiry_info_with_rssi_and_pscan_mode *info;
2533 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002534
Johan Hedberge17acd42011-03-30 23:57:16 +03002535 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002536 bacpy(&data.bdaddr, &info->bdaddr);
2537 data.pscan_rep_mode = info->pscan_rep_mode;
2538 data.pscan_period_mode = info->pscan_period_mode;
2539 data.pscan_mode = info->pscan_mode;
2540 memcpy(data.dev_class, info->dev_class, 3);
2541 data.clock_offset = info->clock_offset;
2542 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002543 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002544 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002545 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002546 info->dev_class, info->rssi,
2547 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002548 }
2549 } else {
2550 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2551
Johan Hedberge17acd42011-03-30 23:57:16 +03002552 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002553 bacpy(&data.bdaddr, &info->bdaddr);
2554 data.pscan_rep_mode = info->pscan_rep_mode;
2555 data.pscan_period_mode = info->pscan_period_mode;
2556 data.pscan_mode = 0x00;
2557 memcpy(data.dev_class, info->dev_class, 3);
2558 data.clock_offset = info->clock_offset;
2559 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002560 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002561 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002562 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002563 info->dev_class, info->rssi,
2564 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002565 }
2566 }
2567
2568 hci_dev_unlock(hdev);
2569}
2570
2571static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2572{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002573 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2574 struct hci_conn *conn;
2575
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002576 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002577
Marcel Holtmann41a96212008-07-14 20:13:48 +02002578 hci_dev_lock(hdev);
2579
2580 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002581 if (!conn)
2582 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002583
Johan Hedbergccd556f2010-11-10 17:11:51 +02002584 if (!ev->status && ev->page == 0x01) {
2585 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002586
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002587 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2588 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002589 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002590
Johan Hedbergccd556f2010-11-10 17:11:51 +02002591 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002592 }
2593
Johan Hedbergccd556f2010-11-10 17:11:51 +02002594 if (conn->state != BT_CONFIG)
2595 goto unlock;
2596
Johan Hedberg127178d2010-11-18 22:22:29 +02002597 if (!ev->status) {
2598 struct hci_cp_remote_name_req cp;
2599 memset(&cp, 0, sizeof(cp));
2600 bacpy(&cp.bdaddr, &conn->dst);
2601 cp.pscan_rep_mode = 0x02;
2602 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2603 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002604
Johan Hedberg127178d2010-11-18 22:22:29 +02002605 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002606 conn->state = BT_CONNECTED;
2607 hci_proto_connect_cfm(conn, ev->status);
2608 hci_conn_put(conn);
2609 }
2610
2611unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002612 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002613}
2614
2615static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2616{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002617 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2618 struct hci_conn *conn;
2619
2620 BT_DBG("%s status %d", hdev->name, ev->status);
2621
2622 hci_dev_lock(hdev);
2623
2624 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002625 if (!conn) {
2626 if (ev->link_type == ESCO_LINK)
2627 goto unlock;
2628
2629 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2630 if (!conn)
2631 goto unlock;
2632
2633 conn->type = SCO_LINK;
2634 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002635
Marcel Holtmann732547f2009-04-19 19:14:14 +02002636 switch (ev->status) {
2637 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002638 conn->handle = __le16_to_cpu(ev->handle);
2639 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002640
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002641 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002642 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002643 break;
2644
Stephen Coe705e5712010-02-16 11:29:44 -05002645 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002646 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002647 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002648 case 0x1f: /* Unspecified error */
2649 if (conn->out && conn->attempt < 2) {
2650 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2651 (hdev->esco_type & EDR_ESCO_MASK);
2652 hci_setup_sync(conn, conn->link->handle);
2653 goto unlock;
2654 }
2655 /* fall through */
2656
2657 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002658 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002659 break;
2660 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002661
2662 hci_proto_connect_cfm(conn, ev->status);
2663 if (ev->status)
2664 hci_conn_del(conn);
2665
2666unlock:
2667 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002668}
2669
2670static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2671{
2672 BT_DBG("%s", hdev->name);
2673}
2674
Marcel Holtmann04837f62006-07-03 10:02:33 +02002675static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2676{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002677 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002678
2679 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002680}
2681
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002682static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2683{
2684 struct inquiry_data data;
2685 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2686 int num_rsp = *((__u8 *) skb->data);
2687
2688 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2689
2690 if (!num_rsp)
2691 return;
2692
2693 hci_dev_lock(hdev);
2694
Johan Hedberge17acd42011-03-30 23:57:16 +03002695 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002696 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002697 data.pscan_rep_mode = info->pscan_rep_mode;
2698 data.pscan_period_mode = info->pscan_period_mode;
2699 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002700 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002701 data.clock_offset = info->clock_offset;
2702 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002703 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002704 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002705 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg4c659c32011-11-07 23:13:39 +02002706 info->dev_class, info->rssi, info->data);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002707 }
2708
2709 hci_dev_unlock(hdev);
2710}
2711
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002712static inline u8 hci_get_auth_req(struct hci_conn *conn)
2713{
2714 /* If remote requests dedicated bonding follow that lead */
2715 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2716 /* If both remote and local IO capabilities allow MITM
2717 * protection then require it, otherwise don't */
2718 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2719 return 0x02;
2720 else
2721 return 0x03;
2722 }
2723
2724 /* If remote requests no-bonding follow that lead */
2725 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002726 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002727
2728 return conn->auth_type;
2729}
2730
Marcel Holtmann04936842008-07-14 20:13:48 +02002731static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2732{
2733 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2734 struct hci_conn *conn;
2735
2736 BT_DBG("%s", hdev->name);
2737
2738 hci_dev_lock(hdev);
2739
2740 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002741 if (!conn)
2742 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002743
Johan Hedberg03b555e2011-01-04 15:40:05 +02002744 hci_conn_hold(conn);
2745
2746 if (!test_bit(HCI_MGMT, &hdev->flags))
2747 goto unlock;
2748
2749 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
2750 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002751 struct hci_cp_io_capability_reply cp;
2752
2753 bacpy(&cp.bdaddr, &ev->bdaddr);
2754 cp.capability = conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07002755 conn->auth_type = hci_get_auth_req(conn);
2756 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002757
Szymon Jancce85ee12011-03-22 13:12:23 +01002758 if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
2759 hci_find_remote_oob_data(hdev, &conn->dst))
2760 cp.oob_data = 0x01;
2761 else
2762 cp.oob_data = 0x00;
2763
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002764 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2765 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002766 } else {
2767 struct hci_cp_io_capability_neg_reply cp;
2768
2769 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002770 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02002771
2772 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2773 sizeof(cp), &cp);
2774 }
2775
2776unlock:
2777 hci_dev_unlock(hdev);
2778}
2779
2780static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2781{
2782 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2783 struct hci_conn *conn;
2784
2785 BT_DBG("%s", hdev->name);
2786
2787 hci_dev_lock(hdev);
2788
2789 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2790 if (!conn)
2791 goto unlock;
2792
Johan Hedberg03b555e2011-01-04 15:40:05 +02002793 conn->remote_cap = ev->capability;
2794 conn->remote_oob = ev->oob_data;
2795 conn->remote_auth = ev->authentication;
2796
2797unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002798 hci_dev_unlock(hdev);
2799}
2800
Johan Hedberga5c29682011-02-19 12:05:57 -03002801static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2802 struct sk_buff *skb)
2803{
2804 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002805 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07002806 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03002807
2808 BT_DBG("%s", hdev->name);
2809
2810 hci_dev_lock(hdev);
2811
Johan Hedberg7a828902011-04-28 11:28:53 -07002812 if (!test_bit(HCI_MGMT, &hdev->flags))
2813 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03002814
Johan Hedberg7a828902011-04-28 11:28:53 -07002815 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2816 if (!conn)
2817 goto unlock;
2818
2819 loc_mitm = (conn->auth_type & 0x01);
2820 rem_mitm = (conn->remote_auth & 0x01);
2821
2822 /* If we require MITM but the remote device can't provide that
2823 * (it has NoInputNoOutput) then reject the confirmation
2824 * request. The only exception is when we're dedicated bonding
2825 * initiators (connect_cfm_cb set) since then we always have the MITM
2826 * bit set. */
2827 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
2828 BT_DBG("Rejecting request: remote device can't provide MITM");
2829 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
2830 sizeof(ev->bdaddr), &ev->bdaddr);
2831 goto unlock;
2832 }
2833
2834 /* If no side requires MITM protection; auto-accept */
2835 if ((!loc_mitm || conn->remote_cap == 0x03) &&
2836 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002837
2838 /* If we're not the initiators request authorization to
2839 * proceed from user space (mgmt_user_confirm with
2840 * confirm_hint set to 1). */
2841 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
2842 BT_DBG("Confirming auto-accept as acceptor");
2843 confirm_hint = 1;
2844 goto confirm;
2845 }
2846
Johan Hedberg9f616562011-04-28 11:28:54 -07002847 BT_DBG("Auto-accept of user confirmation with %ums delay",
2848 hdev->auto_accept_delay);
2849
2850 if (hdev->auto_accept_delay > 0) {
2851 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
2852 mod_timer(&conn->auto_accept_timer, jiffies + delay);
2853 goto unlock;
2854 }
2855
Johan Hedberg7a828902011-04-28 11:28:53 -07002856 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
2857 sizeof(ev->bdaddr), &ev->bdaddr);
2858 goto unlock;
2859 }
2860
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002861confirm:
Johan Hedberg744cf192011-11-08 20:40:14 +02002862 mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002863 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07002864
2865unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03002866 hci_dev_unlock(hdev);
2867}
2868
Brian Gix1143d452011-11-23 08:28:34 -08002869static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
2870 struct sk_buff *skb)
2871{
2872 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
2873
2874 BT_DBG("%s", hdev->name);
2875
2876 hci_dev_lock(hdev);
2877
2878 if (test_bit(HCI_MGMT, &hdev->flags))
2879 mgmt_user_passkey_request(hdev, &ev->bdaddr);
2880
2881 hci_dev_unlock(hdev);
2882}
2883
Marcel Holtmann04936842008-07-14 20:13:48 +02002884static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2885{
2886 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
2887 struct hci_conn *conn;
2888
2889 BT_DBG("%s", hdev->name);
2890
2891 hci_dev_lock(hdev);
2892
2893 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03002894 if (!conn)
2895 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002896
Johan Hedberg2a611692011-02-19 12:06:00 -03002897 /* To avoid duplicate auth_failed events to user space we check
2898 * the HCI_CONN_AUTH_PEND flag which will be set if we
2899 * initiated the authentication. A traditional auth_complete
2900 * event gets always produced as initiator and is also mapped to
2901 * the mgmt_auth_failed event */
2902 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
Johan Hedberg744cf192011-11-08 20:40:14 +02002903 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03002904
2905 hci_conn_put(conn);
2906
2907unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002908 hci_dev_unlock(hdev);
2909}
2910
Marcel Holtmann41a96212008-07-14 20:13:48 +02002911static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2912{
2913 struct hci_ev_remote_host_features *ev = (void *) skb->data;
2914 struct inquiry_entry *ie;
2915
2916 BT_DBG("%s", hdev->name);
2917
2918 hci_dev_lock(hdev);
2919
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002920 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2921 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02002922 ie->data.ssp_mode = (ev->features[0] & 0x01);
2923
2924 hci_dev_unlock(hdev);
2925}
2926
Szymon Janc2763eda2011-03-22 13:12:22 +01002927static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
2928 struct sk_buff *skb)
2929{
2930 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
2931 struct oob_data *data;
2932
2933 BT_DBG("%s", hdev->name);
2934
2935 hci_dev_lock(hdev);
2936
Szymon Jance1ba1f12011-04-06 13:01:59 +02002937 if (!test_bit(HCI_MGMT, &hdev->flags))
2938 goto unlock;
2939
Szymon Janc2763eda2011-03-22 13:12:22 +01002940 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
2941 if (data) {
2942 struct hci_cp_remote_oob_data_reply cp;
2943
2944 bacpy(&cp.bdaddr, &ev->bdaddr);
2945 memcpy(cp.hash, data->hash, sizeof(cp.hash));
2946 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
2947
2948 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
2949 &cp);
2950 } else {
2951 struct hci_cp_remote_oob_data_neg_reply cp;
2952
2953 bacpy(&cp.bdaddr, &ev->bdaddr);
2954 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
2955 &cp);
2956 }
2957
Szymon Jance1ba1f12011-04-06 13:01:59 +02002958unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01002959 hci_dev_unlock(hdev);
2960}
2961
Ville Tervofcd89c02011-02-10 22:38:47 -03002962static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2963{
2964 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2965 struct hci_conn *conn;
2966
2967 BT_DBG("%s status %d", hdev->name, ev->status);
2968
2969 hci_dev_lock(hdev);
2970
2971 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03002972 if (!conn) {
2973 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
2974 if (!conn) {
2975 BT_ERR("No memory for new connection");
2976 hci_dev_unlock(hdev);
2977 return;
2978 }
Andre Guedes29b79882011-05-31 14:20:54 -03002979
2980 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03002981 }
Ville Tervofcd89c02011-02-10 22:38:47 -03002982
2983 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02002984 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
2985 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03002986 hci_proto_connect_cfm(conn, ev->status);
2987 conn->state = BT_CLOSED;
2988 hci_conn_del(conn);
2989 goto unlock;
2990 }
2991
Johan Hedberg48264f02011-11-09 13:58:58 +02002992 mgmt_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03002993
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03002994 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03002995 conn->handle = __le16_to_cpu(ev->handle);
2996 conn->state = BT_CONNECTED;
2997
2998 hci_conn_hold_device(conn);
2999 hci_conn_add_sysfs(conn);
3000
3001 hci_proto_connect_cfm(conn, ev->status);
3002
3003unlock:
3004 hci_dev_unlock(hdev);
3005}
3006
Andre Guedes9aa04c92011-05-26 16:23:51 -03003007static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3008 struct sk_buff *skb)
3009{
Andre Guedese95beb42011-09-26 20:48:35 -03003010 u8 num_reports = skb->data[0];
3011 void *ptr = &skb->data[1];
Andre Guedes9aa04c92011-05-26 16:23:51 -03003012
3013 hci_dev_lock(hdev);
3014
Andre Guedese95beb42011-09-26 20:48:35 -03003015 while (num_reports--) {
3016 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003017
Andre Guedes9aa04c92011-05-26 16:23:51 -03003018 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003019
3020 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003021 }
3022
3023 hci_dev_unlock(hdev);
3024}
3025
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003026static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3027 struct sk_buff *skb)
3028{
3029 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3030 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003031 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003032 struct hci_conn *conn;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003033 struct link_key *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003034
3035 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3036
3037 hci_dev_lock(hdev);
3038
3039 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003040 if (conn == NULL)
3041 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003042
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003043 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3044 if (ltk == NULL)
3045 goto not_found;
3046
3047 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003048 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes726b4ff2011-07-08 18:31:45 -03003049 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003050
3051 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3052
3053 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003054
3055 return;
3056
3057not_found:
3058 neg.handle = ev->handle;
3059 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3060 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003061}
3062
Ville Tervofcd89c02011-02-10 22:38:47 -03003063static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3064{
3065 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3066
3067 skb_pull(skb, sizeof(*le_ev));
3068
3069 switch (le_ev->subevent) {
3070 case HCI_EV_LE_CONN_COMPLETE:
3071 hci_le_conn_complete_evt(hdev, skb);
3072 break;
3073
Andre Guedes9aa04c92011-05-26 16:23:51 -03003074 case HCI_EV_LE_ADVERTISING_REPORT:
3075 hci_le_adv_report_evt(hdev, skb);
3076 break;
3077
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003078 case HCI_EV_LE_LTK_REQ:
3079 hci_le_ltk_request_evt(hdev, skb);
3080 break;
3081
Ville Tervofcd89c02011-02-10 22:38:47 -03003082 default:
3083 break;
3084 }
3085}
3086
Linus Torvalds1da177e2005-04-16 15:20:36 -07003087void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3088{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003089 struct hci_event_hdr *hdr = (void *) skb->data;
3090 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003091
3092 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3093
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003094 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003095 case HCI_EV_INQUIRY_COMPLETE:
3096 hci_inquiry_complete_evt(hdev, skb);
3097 break;
3098
3099 case HCI_EV_INQUIRY_RESULT:
3100 hci_inquiry_result_evt(hdev, skb);
3101 break;
3102
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003103 case HCI_EV_CONN_COMPLETE:
3104 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003105 break;
3106
Linus Torvalds1da177e2005-04-16 15:20:36 -07003107 case HCI_EV_CONN_REQUEST:
3108 hci_conn_request_evt(hdev, skb);
3109 break;
3110
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111 case HCI_EV_DISCONN_COMPLETE:
3112 hci_disconn_complete_evt(hdev, skb);
3113 break;
3114
Linus Torvalds1da177e2005-04-16 15:20:36 -07003115 case HCI_EV_AUTH_COMPLETE:
3116 hci_auth_complete_evt(hdev, skb);
3117 break;
3118
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003119 case HCI_EV_REMOTE_NAME:
3120 hci_remote_name_evt(hdev, skb);
3121 break;
3122
Linus Torvalds1da177e2005-04-16 15:20:36 -07003123 case HCI_EV_ENCRYPT_CHANGE:
3124 hci_encrypt_change_evt(hdev, skb);
3125 break;
3126
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003127 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3128 hci_change_link_key_complete_evt(hdev, skb);
3129 break;
3130
3131 case HCI_EV_REMOTE_FEATURES:
3132 hci_remote_features_evt(hdev, skb);
3133 break;
3134
3135 case HCI_EV_REMOTE_VERSION:
3136 hci_remote_version_evt(hdev, skb);
3137 break;
3138
3139 case HCI_EV_QOS_SETUP_COMPLETE:
3140 hci_qos_setup_complete_evt(hdev, skb);
3141 break;
3142
3143 case HCI_EV_CMD_COMPLETE:
3144 hci_cmd_complete_evt(hdev, skb);
3145 break;
3146
3147 case HCI_EV_CMD_STATUS:
3148 hci_cmd_status_evt(hdev, skb);
3149 break;
3150
3151 case HCI_EV_ROLE_CHANGE:
3152 hci_role_change_evt(hdev, skb);
3153 break;
3154
3155 case HCI_EV_NUM_COMP_PKTS:
3156 hci_num_comp_pkts_evt(hdev, skb);
3157 break;
3158
3159 case HCI_EV_MODE_CHANGE:
3160 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161 break;
3162
3163 case HCI_EV_PIN_CODE_REQ:
3164 hci_pin_code_request_evt(hdev, skb);
3165 break;
3166
3167 case HCI_EV_LINK_KEY_REQ:
3168 hci_link_key_request_evt(hdev, skb);
3169 break;
3170
3171 case HCI_EV_LINK_KEY_NOTIFY:
3172 hci_link_key_notify_evt(hdev, skb);
3173 break;
3174
3175 case HCI_EV_CLOCK_OFFSET:
3176 hci_clock_offset_evt(hdev, skb);
3177 break;
3178
Marcel Holtmanna8746412008-07-14 20:13:46 +02003179 case HCI_EV_PKT_TYPE_CHANGE:
3180 hci_pkt_type_change_evt(hdev, skb);
3181 break;
3182
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003183 case HCI_EV_PSCAN_REP_MODE:
3184 hci_pscan_rep_mode_evt(hdev, skb);
3185 break;
3186
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003187 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3188 hci_inquiry_result_with_rssi_evt(hdev, skb);
3189 break;
3190
3191 case HCI_EV_REMOTE_EXT_FEATURES:
3192 hci_remote_ext_features_evt(hdev, skb);
3193 break;
3194
3195 case HCI_EV_SYNC_CONN_COMPLETE:
3196 hci_sync_conn_complete_evt(hdev, skb);
3197 break;
3198
3199 case HCI_EV_SYNC_CONN_CHANGED:
3200 hci_sync_conn_changed_evt(hdev, skb);
3201 break;
3202
Marcel Holtmann04837f62006-07-03 10:02:33 +02003203 case HCI_EV_SNIFF_SUBRATE:
3204 hci_sniff_subrate_evt(hdev, skb);
3205 break;
3206
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003207 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3208 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003209 break;
3210
Marcel Holtmann04936842008-07-14 20:13:48 +02003211 case HCI_EV_IO_CAPA_REQUEST:
3212 hci_io_capa_request_evt(hdev, skb);
3213 break;
3214
Johan Hedberg03b555e2011-01-04 15:40:05 +02003215 case HCI_EV_IO_CAPA_REPLY:
3216 hci_io_capa_reply_evt(hdev, skb);
3217 break;
3218
Johan Hedberga5c29682011-02-19 12:05:57 -03003219 case HCI_EV_USER_CONFIRM_REQUEST:
3220 hci_user_confirm_request_evt(hdev, skb);
3221 break;
3222
Brian Gix1143d452011-11-23 08:28:34 -08003223 case HCI_EV_USER_PASSKEY_REQUEST:
3224 hci_user_passkey_request_evt(hdev, skb);
3225 break;
3226
Marcel Holtmann04936842008-07-14 20:13:48 +02003227 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3228 hci_simple_pair_complete_evt(hdev, skb);
3229 break;
3230
Marcel Holtmann41a96212008-07-14 20:13:48 +02003231 case HCI_EV_REMOTE_HOST_FEATURES:
3232 hci_remote_host_features_evt(hdev, skb);
3233 break;
3234
Ville Tervofcd89c02011-02-10 22:38:47 -03003235 case HCI_EV_LE_META:
3236 hci_le_meta_evt(hdev, skb);
3237 break;
3238
Szymon Janc2763eda2011-03-22 13:12:22 +01003239 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3240 hci_remote_oob_data_request_evt(hdev, skb);
3241 break;
3242
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003243 default:
3244 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003245 break;
3246 }
3247
3248 kfree_skb(skb);
3249 hdev->stat.evt_rx++;
3250}
3251
3252/* Generate internal stack event */
3253void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3254{
3255 struct hci_event_hdr *hdr;
3256 struct hci_ev_stack_internal *ev;
3257 struct sk_buff *skb;
3258
3259 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3260 if (!skb)
3261 return;
3262
3263 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3264 hdr->evt = HCI_EV_STACK_INTERNAL;
3265 hdr->plen = sizeof(*ev) + dlen;
3266
3267 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3268 ev->type = type;
3269 memcpy(ev->data, data, dlen);
3270
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003271 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003272 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003273
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003274 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003276 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277 kfree_skb(skb);
3278}
Andre Guedese6100a22011-06-30 19:20:54 -03003279
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003280module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003281MODULE_PARM_DESC(enable_le, "Enable LE support");