blob: 4221bd256bddfd89e147f1605f0dd334aa042ea6 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
38#include <linux/notifier.h>
39#include <net/sock.h>
40
41#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020042#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <asm/unaligned.h>
44
45#include <net/bluetooth/bluetooth.h>
46#include <net/bluetooth/hci_core.h>
47
Rusty Russelleb939922011-12-19 14:08:01 +000048static bool enable_le;
Andre Guedese6100a22011-06-30 19:20:54 -030049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050/* Handle HCI Event packets */
51
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070053{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020054 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Marcel Holtmanna9de9242007-10-20 13:33:56 +020056 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Andre Guedese6d465c2011-11-09 17:14:26 -030058 if (status) {
59 hci_dev_lock(hdev);
60 mgmt_stop_discovery_failed(hdev, status);
61 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020062 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030063 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Andre Guedes89352e72011-11-04 14:16:53 -030065 clear_bit(HCI_INQUIRY, &hdev->flags);
66
Johan Hedberg56e5cb82011-11-08 20:40:16 +020067 hci_dev_lock(hdev);
Johan 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{
Andrei Emeltchenkoe61ef492011-12-19 16:31:27 +0200559 if (hdev->dev_type != HCI_BREDR)
560 return;
561
Johan Hedbergd5859e22011-01-25 01:19:58 +0200562 hci_setup_event_mask(hdev);
563
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200564 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200565 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
566
567 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
568 u8 mode = 0x01;
569 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
570 }
571
572 if (hdev->features[3] & LMP_RSSI_INQ)
573 hci_setup_inquiry_mode(hdev);
574
575 if (hdev->features[7] & LMP_INQ_TX_PWR)
576 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300577
578 if (hdev->features[7] & LMP_EXTFEATURES) {
579 struct hci_cp_read_local_ext_features cp;
580
581 cp.page = 0x01;
582 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
583 sizeof(cp), &cp);
584 }
Andre Guedese6100a22011-06-30 19:20:54 -0300585
586 if (hdev->features[4] & LMP_LE)
587 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200588}
589
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200590static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
591{
592 struct hci_rp_read_local_version *rp = (void *) skb->data;
593
594 BT_DBG("%s status 0x%x", hdev->name, rp->status);
595
596 if (rp->status)
597 return;
598
599 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200600 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200601 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200602 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200603 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200604
605 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
606 hdev->manufacturer,
607 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200608
609 if (test_bit(HCI_INIT, &hdev->flags))
610 hci_setup(hdev);
611}
612
613static void hci_setup_link_policy(struct hci_dev *hdev)
614{
615 u16 link_policy = 0;
616
617 if (hdev->features[0] & LMP_RSWITCH)
618 link_policy |= HCI_LP_RSWITCH;
619 if (hdev->features[0] & LMP_HOLD)
620 link_policy |= HCI_LP_HOLD;
621 if (hdev->features[0] & LMP_SNIFF)
622 link_policy |= HCI_LP_SNIFF;
623 if (hdev->features[1] & LMP_PARK)
624 link_policy |= HCI_LP_PARK;
625
626 link_policy = cpu_to_le16(link_policy);
627 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
628 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200629}
630
631static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
632{
633 struct hci_rp_read_local_commands *rp = (void *) skb->data;
634
635 BT_DBG("%s status 0x%x", hdev->name, rp->status);
636
637 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200638 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200639
640 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200641
642 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
643 hci_setup_link_policy(hdev);
644
645done:
646 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200647}
648
649static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
650{
651 struct hci_rp_read_local_features *rp = (void *) skb->data;
652
653 BT_DBG("%s status 0x%x", hdev->name, rp->status);
654
655 if (rp->status)
656 return;
657
658 memcpy(hdev->features, rp->features, 8);
659
660 /* Adjust default settings according to features
661 * supported by device. */
662
663 if (hdev->features[0] & LMP_3SLOT)
664 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
665
666 if (hdev->features[0] & LMP_5SLOT)
667 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
668
669 if (hdev->features[1] & LMP_HV2) {
670 hdev->pkt_type |= (HCI_HV2);
671 hdev->esco_type |= (ESCO_HV2);
672 }
673
674 if (hdev->features[1] & LMP_HV3) {
675 hdev->pkt_type |= (HCI_HV3);
676 hdev->esco_type |= (ESCO_HV3);
677 }
678
679 if (hdev->features[3] & LMP_ESCO)
680 hdev->esco_type |= (ESCO_EV3);
681
682 if (hdev->features[4] & LMP_EV4)
683 hdev->esco_type |= (ESCO_EV4);
684
685 if (hdev->features[4] & LMP_EV5)
686 hdev->esco_type |= (ESCO_EV5);
687
Marcel Holtmannefc76882009-02-06 09:13:37 +0100688 if (hdev->features[5] & LMP_EDR_ESCO_2M)
689 hdev->esco_type |= (ESCO_2EV3);
690
691 if (hdev->features[5] & LMP_EDR_ESCO_3M)
692 hdev->esco_type |= (ESCO_3EV3);
693
694 if (hdev->features[5] & LMP_EDR_3S_ESCO)
695 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
696
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200697 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
698 hdev->features[0], hdev->features[1],
699 hdev->features[2], hdev->features[3],
700 hdev->features[4], hdev->features[5],
701 hdev->features[6], hdev->features[7]);
702}
703
Andre Guedes971e3a42011-06-30 19:20:52 -0300704static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
705 struct sk_buff *skb)
706{
707 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
708
709 BT_DBG("%s status 0x%x", hdev->name, rp->status);
710
711 if (rp->status)
712 return;
713
714 memcpy(hdev->extfeatures, rp->features, 8);
715
716 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
717}
718
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200719static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
720 struct sk_buff *skb)
721{
722 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
723
724 BT_DBG("%s status 0x%x", hdev->name, rp->status);
725
726 if (rp->status)
727 return;
728
729 hdev->flow_ctl_mode = rp->mode;
730
731 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
732}
733
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200734static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
735{
736 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
737
738 BT_DBG("%s status 0x%x", hdev->name, rp->status);
739
740 if (rp->status)
741 return;
742
743 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
744 hdev->sco_mtu = rp->sco_mtu;
745 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
746 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
747
748 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
749 hdev->sco_mtu = 64;
750 hdev->sco_pkts = 8;
751 }
752
753 hdev->acl_cnt = hdev->acl_pkts;
754 hdev->sco_cnt = hdev->sco_pkts;
755
756 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
757 hdev->acl_mtu, hdev->acl_pkts,
758 hdev->sco_mtu, hdev->sco_pkts);
759}
760
761static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
762{
763 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
764
765 BT_DBG("%s status 0x%x", hdev->name, rp->status);
766
767 if (!rp->status)
768 bacpy(&hdev->bdaddr, &rp->bdaddr);
769
Johan Hedberg23bb5762010-12-21 23:01:27 +0200770 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
771}
772
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200773static void hci_cc_read_data_block_size(struct hci_dev *hdev,
774 struct sk_buff *skb)
775{
776 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
777
778 BT_DBG("%s status 0x%x", hdev->name, rp->status);
779
780 if (rp->status)
781 return;
782
783 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
784 hdev->block_len = __le16_to_cpu(rp->block_len);
785 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
786
787 hdev->block_cnt = hdev->num_blocks;
788
789 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
790 hdev->block_cnt, hdev->block_len);
791
792 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
793}
794
Johan Hedberg23bb5762010-12-21 23:01:27 +0200795static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
796{
797 __u8 status = *((__u8 *) skb->data);
798
799 BT_DBG("%s status 0x%x", hdev->name, status);
800
801 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200802}
803
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300804static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
805 struct sk_buff *skb)
806{
807 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
808
809 BT_DBG("%s status 0x%x", hdev->name, rp->status);
810
811 if (rp->status)
812 return;
813
814 hdev->amp_status = rp->amp_status;
815 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
816 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
817 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
818 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
819 hdev->amp_type = rp->amp_type;
820 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
821 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
822 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
823 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
824
825 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
826}
827
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200828static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
829 struct sk_buff *skb)
830{
831 __u8 status = *((__u8 *) skb->data);
832
833 BT_DBG("%s status 0x%x", hdev->name, status);
834
835 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
836}
837
Johan Hedbergd5859e22011-01-25 01:19:58 +0200838static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
839{
840 __u8 status = *((__u8 *) skb->data);
841
842 BT_DBG("%s status 0x%x", hdev->name, status);
843
844 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
845}
846
847static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
848 struct sk_buff *skb)
849{
850 __u8 status = *((__u8 *) skb->data);
851
852 BT_DBG("%s status 0x%x", hdev->name, status);
853
854 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
855}
856
857static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
858 struct sk_buff *skb)
859{
860 __u8 status = *((__u8 *) skb->data);
861
862 BT_DBG("%s status 0x%x", hdev->name, status);
863
864 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
865}
866
867static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
868{
869 __u8 status = *((__u8 *) skb->data);
870
871 BT_DBG("%s status 0x%x", hdev->name, status);
872
873 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
874}
875
Johan Hedberg980e1a52011-01-22 06:10:07 +0200876static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
877{
878 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
879 struct hci_cp_pin_code_reply *cp;
880 struct hci_conn *conn;
881
882 BT_DBG("%s status 0x%x", hdev->name, rp->status);
883
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200884 hci_dev_lock(hdev);
885
Johan Hedberg980e1a52011-01-22 06:10:07 +0200886 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200887 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200888
889 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200890 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200891
892 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
893 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200894 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200895
896 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
897 if (conn)
898 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200899
900unlock:
901 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200902}
903
904static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
905{
906 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
907
908 BT_DBG("%s status 0x%x", hdev->name, rp->status);
909
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200910 hci_dev_lock(hdev);
911
Johan Hedberg980e1a52011-01-22 06:10:07 +0200912 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200913 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200914 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200915
916 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200917}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200918
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300919static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
920 struct sk_buff *skb)
921{
922 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
923
924 BT_DBG("%s status 0x%x", hdev->name, rp->status);
925
926 if (rp->status)
927 return;
928
929 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
930 hdev->le_pkts = rp->le_max_pkt;
931
932 hdev->le_cnt = hdev->le_pkts;
933
934 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
935
936 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
937}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200938
Johan Hedberga5c29682011-02-19 12:05:57 -0300939static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
940{
941 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
942
943 BT_DBG("%s status 0x%x", hdev->name, rp->status);
944
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200945 hci_dev_lock(hdev);
946
Johan Hedberga5c29682011-02-19 12:05:57 -0300947 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200948 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300949 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200950
951 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300952}
953
954static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
955 struct sk_buff *skb)
956{
957 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
958
959 BT_DBG("%s status 0x%x", hdev->name, rp->status);
960
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200961 hci_dev_lock(hdev);
962
Johan Hedberga5c29682011-02-19 12:05:57 -0300963 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200964 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300965 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200966
967 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300968}
969
Brian Gix1143d452011-11-23 08:28:34 -0800970static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
971{
972 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
973
974 BT_DBG("%s status 0x%x", hdev->name, rp->status);
975
976 hci_dev_lock(hdev);
977
978 if (test_bit(HCI_MGMT, &hdev->flags))
979 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr,
980 rp->status);
981
982 hci_dev_unlock(hdev);
983}
984
985static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
986 struct sk_buff *skb)
987{
988 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
989
990 BT_DBG("%s status 0x%x", hdev->name, rp->status);
991
992 hci_dev_lock(hdev);
993
994 if (test_bit(HCI_MGMT, &hdev->flags))
995 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
996 rp->status);
997
998 hci_dev_unlock(hdev);
999}
1000
Szymon Jancc35938b2011-03-22 13:12:21 +01001001static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1002 struct sk_buff *skb)
1003{
1004 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1005
1006 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1007
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001008 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001009 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001010 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001011 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001012}
1013
Andre Guedes07f7fa52011-12-02 21:13:31 +09001014static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1015{
1016 __u8 status = *((__u8 *) skb->data);
1017
1018 BT_DBG("%s status 0x%x", hdev->name, status);
1019}
1020
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001021static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1022 struct sk_buff *skb)
1023{
1024 struct hci_cp_le_set_scan_enable *cp;
1025 __u8 status = *((__u8 *) skb->data);
1026
1027 BT_DBG("%s status 0x%x", hdev->name, status);
1028
1029 if (status)
1030 return;
1031
1032 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1033 if (!cp)
1034 return;
1035
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001036 switch (cp->enable) {
1037 case LE_SCANNING_ENABLED:
Andre Guedesd23264a2011-11-25 20:53:38 -03001038 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1039
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001040 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001041
1042 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001043 hci_adv_entries_clear(hdev);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001044 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001045 break;
1046
1047 case LE_SCANNING_DISABLED:
Andre Guedesd23264a2011-11-25 20:53:38 -03001048 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1049
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001050 cancel_delayed_work_sync(&hdev->adv_work);
1051 queue_delayed_work(hdev->workqueue, &hdev->adv_work,
1052 jiffies + ADV_CLEAR_TIMEOUT);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001053 break;
1054
1055 default:
1056 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1057 break;
Andre Guedes35815082011-05-26 16:23:53 -03001058 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001059}
1060
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001061static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1062{
1063 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1064
1065 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1066
1067 if (rp->status)
1068 return;
1069
1070 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1071}
1072
1073static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1074{
1075 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1076
1077 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1078
1079 if (rp->status)
1080 return;
1081
1082 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1083}
1084
Andre Guedesf9b49302011-06-30 19:20:53 -03001085static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1086 struct sk_buff *skb)
1087{
1088 struct hci_cp_read_local_ext_features cp;
1089 __u8 status = *((__u8 *) skb->data);
1090
1091 BT_DBG("%s status 0x%x", hdev->name, status);
1092
1093 if (status)
1094 return;
1095
1096 cp.page = 0x01;
1097 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1098}
1099
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001100static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1101{
1102 BT_DBG("%s status 0x%x", hdev->name, status);
1103
1104 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001105 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001106 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001107 hci_dev_lock(hdev);
Johan Hedberg164a6e72011-11-01 17:06:44 +02001108 if (test_bit(HCI_MGMT, &hdev->flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001109 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001110 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001111 return;
1112 }
1113
Andre Guedes89352e72011-11-04 14:16:53 -03001114 set_bit(HCI_INQUIRY, &hdev->flags);
1115
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001116 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001117 mgmt_discovering(hdev, 1);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001118 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001119}
1120
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1122{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001123 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001126 BT_DBG("%s status 0x%x", hdev->name, status);
1127
1128 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 if (!cp)
1130 return;
1131
1132 hci_dev_lock(hdev);
1133
1134 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1135
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001136 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137
1138 if (status) {
1139 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001140 if (status != 0x0c || conn->attempt > 2) {
1141 conn->state = BT_CLOSED;
1142 hci_proto_connect_cfm(conn, status);
1143 hci_conn_del(conn);
1144 } else
1145 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 }
1147 } else {
1148 if (!conn) {
1149 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1150 if (conn) {
1151 conn->out = 1;
1152 conn->link_mode |= HCI_LM_MASTER;
1153 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001154 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155 }
1156 }
1157
1158 hci_dev_unlock(hdev);
1159}
1160
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001161static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001163 struct hci_cp_add_sco *cp;
1164 struct hci_conn *acl, *sco;
1165 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001167 BT_DBG("%s status 0x%x", hdev->name, status);
1168
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001169 if (!status)
1170 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001172 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1173 if (!cp)
1174 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001176 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001178 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001179
1180 hci_dev_lock(hdev);
1181
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001182 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001183 if (acl) {
1184 sco = acl->link;
1185 if (sco) {
1186 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001187
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001188 hci_proto_connect_cfm(sco, status);
1189 hci_conn_del(sco);
1190 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001191 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001192
1193 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194}
1195
Marcel Holtmannf8558552008-07-14 20:13:49 +02001196static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1197{
1198 struct hci_cp_auth_requested *cp;
1199 struct hci_conn *conn;
1200
1201 BT_DBG("%s status 0x%x", hdev->name, status);
1202
1203 if (!status)
1204 return;
1205
1206 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1207 if (!cp)
1208 return;
1209
1210 hci_dev_lock(hdev);
1211
1212 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1213 if (conn) {
1214 if (conn->state == BT_CONFIG) {
1215 hci_proto_connect_cfm(conn, status);
1216 hci_conn_put(conn);
1217 }
1218 }
1219
1220 hci_dev_unlock(hdev);
1221}
1222
1223static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1224{
1225 struct hci_cp_set_conn_encrypt *cp;
1226 struct hci_conn *conn;
1227
1228 BT_DBG("%s status 0x%x", hdev->name, status);
1229
1230 if (!status)
1231 return;
1232
1233 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1234 if (!cp)
1235 return;
1236
1237 hci_dev_lock(hdev);
1238
1239 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1240 if (conn) {
1241 if (conn->state == BT_CONFIG) {
1242 hci_proto_connect_cfm(conn, status);
1243 hci_conn_put(conn);
1244 }
1245 }
1246
1247 hci_dev_unlock(hdev);
1248}
1249
Johan Hedberg127178d2010-11-18 22:22:29 +02001250static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001251 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001252{
Johan Hedberg392599b2010-11-18 22:22:28 +02001253 if (conn->state != BT_CONFIG || !conn->out)
1254 return 0;
1255
Johan Hedberg765c2a92011-01-19 12:06:52 +05301256 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001257 return 0;
1258
1259 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001260 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedberg392599b2010-11-18 22:22:28 +02001261 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001262 conn->pending_sec_level != BT_SECURITY_HIGH &&
1263 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001264 return 0;
1265
Johan Hedberg392599b2010-11-18 22:22:28 +02001266 return 1;
1267}
1268
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001269static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1270{
Johan Hedberg127178d2010-11-18 22:22:29 +02001271 struct hci_cp_remote_name_req *cp;
1272 struct hci_conn *conn;
1273
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001274 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001275
1276 /* If successful wait for the name req complete event before
1277 * checking for the need to do authentication */
1278 if (!status)
1279 return;
1280
1281 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1282 if (!cp)
1283 return;
1284
1285 hci_dev_lock(hdev);
1286
1287 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001288 if (!conn)
1289 goto unlock;
1290
1291 if (!hci_outgoing_auth_needed(hdev, conn))
1292 goto unlock;
1293
1294 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001295 struct hci_cp_auth_requested cp;
1296 cp.handle = __cpu_to_le16(conn->handle);
1297 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1298 }
1299
Johan Hedberg79c6c702011-04-28 11:28:55 -07001300unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001301 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001302}
1303
Marcel Holtmann769be972008-07-14 20:13:49 +02001304static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1305{
1306 struct hci_cp_read_remote_features *cp;
1307 struct hci_conn *conn;
1308
1309 BT_DBG("%s status 0x%x", hdev->name, status);
1310
1311 if (!status)
1312 return;
1313
1314 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1315 if (!cp)
1316 return;
1317
1318 hci_dev_lock(hdev);
1319
1320 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1321 if (conn) {
1322 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001323 hci_proto_connect_cfm(conn, status);
1324 hci_conn_put(conn);
1325 }
1326 }
1327
1328 hci_dev_unlock(hdev);
1329}
1330
1331static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1332{
1333 struct hci_cp_read_remote_ext_features *cp;
1334 struct hci_conn *conn;
1335
1336 BT_DBG("%s status 0x%x", hdev->name, status);
1337
1338 if (!status)
1339 return;
1340
1341 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1342 if (!cp)
1343 return;
1344
1345 hci_dev_lock(hdev);
1346
1347 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1348 if (conn) {
1349 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001350 hci_proto_connect_cfm(conn, status);
1351 hci_conn_put(conn);
1352 }
1353 }
1354
1355 hci_dev_unlock(hdev);
1356}
1357
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001358static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1359{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001360 struct hci_cp_setup_sync_conn *cp;
1361 struct hci_conn *acl, *sco;
1362 __u16 handle;
1363
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001364 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001365
1366 if (!status)
1367 return;
1368
1369 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1370 if (!cp)
1371 return;
1372
1373 handle = __le16_to_cpu(cp->handle);
1374
1375 BT_DBG("%s handle %d", hdev->name, handle);
1376
1377 hci_dev_lock(hdev);
1378
1379 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001380 if (acl) {
1381 sco = acl->link;
1382 if (sco) {
1383 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001384
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001385 hci_proto_connect_cfm(sco, status);
1386 hci_conn_del(sco);
1387 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001388 }
1389
1390 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001391}
1392
1393static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1394{
1395 struct hci_cp_sniff_mode *cp;
1396 struct hci_conn *conn;
1397
1398 BT_DBG("%s status 0x%x", hdev->name, status);
1399
1400 if (!status)
1401 return;
1402
1403 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1404 if (!cp)
1405 return;
1406
1407 hci_dev_lock(hdev);
1408
1409 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001410 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001411 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1412
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001413 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1414 hci_sco_setup(conn, status);
1415 }
1416
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001417 hci_dev_unlock(hdev);
1418}
1419
1420static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1421{
1422 struct hci_cp_exit_sniff_mode *cp;
1423 struct hci_conn *conn;
1424
1425 BT_DBG("%s status 0x%x", hdev->name, status);
1426
1427 if (!status)
1428 return;
1429
1430 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1431 if (!cp)
1432 return;
1433
1434 hci_dev_lock(hdev);
1435
1436 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001437 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001438 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1439
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001440 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1441 hci_sco_setup(conn, status);
1442 }
1443
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001444 hci_dev_unlock(hdev);
1445}
1446
Ville Tervofcd89c02011-02-10 22:38:47 -03001447static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1448{
1449 struct hci_cp_le_create_conn *cp;
1450 struct hci_conn *conn;
1451
1452 BT_DBG("%s status 0x%x", hdev->name, status);
1453
1454 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1455 if (!cp)
1456 return;
1457
1458 hci_dev_lock(hdev);
1459
1460 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1461
1462 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1463 conn);
1464
1465 if (status) {
1466 if (conn && conn->state == BT_CONNECT) {
1467 conn->state = BT_CLOSED;
1468 hci_proto_connect_cfm(conn, status);
1469 hci_conn_del(conn);
1470 }
1471 } else {
1472 if (!conn) {
1473 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001474 if (conn) {
1475 conn->dst_type = cp->peer_addr_type;
Ville Tervofcd89c02011-02-10 22:38:47 -03001476 conn->out = 1;
Andre Guedes29b79882011-05-31 14:20:54 -03001477 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001478 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001479 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001480 }
1481 }
1482
1483 hci_dev_unlock(hdev);
1484}
1485
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001486static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1487{
1488 BT_DBG("%s status 0x%x", hdev->name, status);
1489}
1490
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001491static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1492{
1493 __u8 status = *((__u8 *) skb->data);
1494
1495 BT_DBG("%s status %d", hdev->name, status);
1496
Johan Hedberg23bb5762010-12-21 23:01:27 +02001497 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001498
1499 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001500
1501 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1502 return;
1503
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001504 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001505 mgmt_discovering(hdev, 0);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001506 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001507}
1508
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1510{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001511 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001512 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 int num_rsp = *((__u8 *) skb->data);
1514
1515 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1516
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001517 if (!num_rsp)
1518 return;
1519
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001521
Johan Hedberge17acd42011-03-30 23:57:16 +03001522 for (; num_rsp; num_rsp--, info++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 bacpy(&data.bdaddr, &info->bdaddr);
1524 data.pscan_rep_mode = info->pscan_rep_mode;
1525 data.pscan_period_mode = info->pscan_period_mode;
1526 data.pscan_mode = info->pscan_mode;
1527 memcpy(data.dev_class, info->dev_class, 3);
1528 data.clock_offset = info->clock_offset;
1529 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001530 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02001532 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg4c659c32011-11-07 23:13:39 +02001533 info->dev_class, 0, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001535
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 hci_dev_unlock(hdev);
1537}
1538
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001539static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001541 struct hci_ev_conn_complete *ev = (void *) skb->data;
1542 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001544 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001545
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001547
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001548 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001549 if (!conn) {
1550 if (ev->link_type != SCO_LINK)
1551 goto unlock;
1552
1553 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1554 if (!conn)
1555 goto unlock;
1556
1557 conn->type = SCO_LINK;
1558 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001559
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001560 if (!ev->status) {
1561 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001562
1563 if (conn->type == ACL_LINK) {
1564 conn->state = BT_CONFIG;
1565 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001566 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg48264f02011-11-09 13:58:58 +02001567 mgmt_connected(hdev, &ev->bdaddr, conn->type,
1568 conn->dst_type);
Marcel Holtmann769be972008-07-14 20:13:49 +02001569 } else
1570 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001571
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001572 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001573 hci_conn_add_sysfs(conn);
1574
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001575 if (test_bit(HCI_AUTH, &hdev->flags))
1576 conn->link_mode |= HCI_LM_AUTH;
1577
1578 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1579 conn->link_mode |= HCI_LM_ENCRYPT;
1580
1581 /* Get remote features */
1582 if (conn->type == ACL_LINK) {
1583 struct hci_cp_read_remote_features cp;
1584 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001585 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1586 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001587 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001588
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001589 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001590 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001591 struct hci_cp_change_conn_ptype cp;
1592 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001593 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1594 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1595 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001596 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001597 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001598 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001599 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001600 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001601 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001602 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001603
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001604 if (conn->type == ACL_LINK)
1605 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001606
Marcel Holtmann769be972008-07-14 20:13:49 +02001607 if (ev->status) {
1608 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001609 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001610 } else if (ev->link_type != ACL_LINK)
1611 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001612
1613unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001615
1616 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617}
1618
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1620{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001621 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 int mask = hdev->link_mode;
1623
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001624 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1625 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626
1627 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1628
Szymon Janc138d22e2011-02-17 16:44:23 +01001629 if ((mask & HCI_LM_ACCEPT) &&
1630 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001632 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634
1635 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001636
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001637 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1638 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001639 memcpy(ie->data.dev_class, ev->dev_class, 3);
1640
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1642 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001643 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1644 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001645 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646 hci_dev_unlock(hdev);
1647 return;
1648 }
1649 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001650
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 memcpy(conn->dev_class, ev->dev_class, 3);
1652 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001653
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 hci_dev_unlock(hdev);
1655
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001656 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1657 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001659 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001661 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1662 cp.role = 0x00; /* Become master */
1663 else
1664 cp.role = 0x01; /* Remain slave */
1665
1666 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1667 sizeof(cp), &cp);
1668 } else {
1669 struct hci_cp_accept_sync_conn_req cp;
1670
1671 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001672 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001673
1674 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1675 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1676 cp.max_latency = cpu_to_le16(0xffff);
1677 cp.content_format = cpu_to_le16(hdev->voice_setting);
1678 cp.retrans_effort = 0xff;
1679
1680 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1681 sizeof(cp), &cp);
1682 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 } else {
1684 /* Connection rejected */
1685 struct hci_cp_reject_conn_req cp;
1686
1687 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001688 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001689 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 }
1691}
1692
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1694{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001695 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001696 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
1698 BT_DBG("%s status %d", hdev->name, ev->status);
1699
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 hci_dev_lock(hdev);
1701
Marcel Holtmann04837f62006-07-03 10:02:33 +02001702 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001703 if (!conn)
1704 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001705
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001706 if (ev->status == 0)
1707 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001709 if (conn->type == ACL_LINK || conn->type == LE_LINK) {
1710 if (ev->status != 0)
1711 mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
1712 else
1713 mgmt_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001714 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001715 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001716
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001717 if (ev->status == 0) {
1718 hci_proto_disconn_cfm(conn, ev->reason);
1719 hci_conn_del(conn);
1720 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001721
1722unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 hci_dev_unlock(hdev);
1724}
1725
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001726static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1727{
1728 struct hci_ev_auth_complete *ev = (void *) skb->data;
1729 struct hci_conn *conn;
1730
1731 BT_DBG("%s status %d", hdev->name, ev->status);
1732
1733 hci_dev_lock(hdev);
1734
1735 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001736 if (!conn)
1737 goto unlock;
1738
1739 if (!ev->status) {
1740 if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) &&
1741 test_bit(HCI_CONN_REAUTH_PEND, &conn->pend)) {
1742 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001743 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001744 conn->link_mode |= HCI_LM_AUTH;
1745 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001746 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001747 } else {
Johan Hedberg744cf192011-11-08 20:40:14 +02001748 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001749 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001750
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001751 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1752 clear_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001753
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001754 if (conn->state == BT_CONFIG) {
1755 if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) {
1756 struct hci_cp_set_conn_encrypt cp;
1757 cp.handle = ev->handle;
1758 cp.encrypt = 0x01;
1759 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1760 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001761 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001762 conn->state = BT_CONNECTED;
1763 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001764 hci_conn_put(conn);
1765 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001766 } else {
1767 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001768
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001769 hci_conn_hold(conn);
1770 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1771 hci_conn_put(conn);
1772 }
1773
1774 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1775 if (!ev->status) {
1776 struct hci_cp_set_conn_encrypt cp;
1777 cp.handle = ev->handle;
1778 cp.encrypt = 0x01;
1779 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1780 &cp);
1781 } else {
1782 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1783 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001784 }
1785 }
1786
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001787unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001788 hci_dev_unlock(hdev);
1789}
1790
1791static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1792{
Johan Hedberg127178d2010-11-18 22:22:29 +02001793 struct hci_ev_remote_name *ev = (void *) skb->data;
1794 struct hci_conn *conn;
1795
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001796 BT_DBG("%s", hdev->name);
1797
1798 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001799
1800 hci_dev_lock(hdev);
1801
Johan Hedberga88a9652011-03-30 13:18:12 +03001802 if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001803 mgmt_remote_name(hdev, &ev->bdaddr, ev->name);
Johan Hedberga88a9652011-03-30 13:18:12 +03001804
Johan Hedberg127178d2010-11-18 22:22:29 +02001805 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001806 if (!conn)
1807 goto unlock;
1808
1809 if (!hci_outgoing_auth_needed(hdev, conn))
1810 goto unlock;
1811
1812 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001813 struct hci_cp_auth_requested cp;
1814 cp.handle = __cpu_to_le16(conn->handle);
1815 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1816 }
1817
Johan Hedberg79c6c702011-04-28 11:28:55 -07001818unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001819 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001820}
1821
1822static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1823{
1824 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1825 struct hci_conn *conn;
1826
1827 BT_DBG("%s status %d", hdev->name, ev->status);
1828
1829 hci_dev_lock(hdev);
1830
1831 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1832 if (conn) {
1833 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001834 if (ev->encrypt) {
1835 /* Encryption implies authentication */
1836 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001837 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001838 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001839 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001840 conn->link_mode &= ~HCI_LM_ENCRYPT;
1841 }
1842
1843 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1844
Marcel Holtmannf8558552008-07-14 20:13:49 +02001845 if (conn->state == BT_CONFIG) {
1846 if (!ev->status)
1847 conn->state = BT_CONNECTED;
1848
1849 hci_proto_connect_cfm(conn, ev->status);
1850 hci_conn_put(conn);
1851 } else
1852 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001853 }
1854
1855 hci_dev_unlock(hdev);
1856}
1857
1858static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1859{
1860 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1861 struct hci_conn *conn;
1862
1863 BT_DBG("%s status %d", hdev->name, ev->status);
1864
1865 hci_dev_lock(hdev);
1866
1867 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1868 if (conn) {
1869 if (!ev->status)
1870 conn->link_mode |= HCI_LM_SECURE;
1871
1872 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1873
1874 hci_key_change_cfm(conn, ev->status);
1875 }
1876
1877 hci_dev_unlock(hdev);
1878}
1879
1880static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1881{
1882 struct hci_ev_remote_features *ev = (void *) skb->data;
1883 struct hci_conn *conn;
1884
1885 BT_DBG("%s status %d", hdev->name, ev->status);
1886
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001887 hci_dev_lock(hdev);
1888
1889 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001890 if (!conn)
1891 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001892
Johan Hedbergccd556f2010-11-10 17:11:51 +02001893 if (!ev->status)
1894 memcpy(conn->features, ev->features, 8);
1895
1896 if (conn->state != BT_CONFIG)
1897 goto unlock;
1898
1899 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1900 struct hci_cp_read_remote_ext_features cp;
1901 cp.handle = ev->handle;
1902 cp.page = 0x01;
1903 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001904 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001905 goto unlock;
1906 }
1907
Johan Hedberg127178d2010-11-18 22:22:29 +02001908 if (!ev->status) {
1909 struct hci_cp_remote_name_req cp;
1910 memset(&cp, 0, sizeof(cp));
1911 bacpy(&cp.bdaddr, &conn->dst);
1912 cp.pscan_rep_mode = 0x02;
1913 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1914 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001915
Johan Hedberg127178d2010-11-18 22:22:29 +02001916 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001917 conn->state = BT_CONNECTED;
1918 hci_proto_connect_cfm(conn, ev->status);
1919 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001920 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001921
Johan Hedbergccd556f2010-11-10 17:11:51 +02001922unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001923 hci_dev_unlock(hdev);
1924}
1925
1926static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1927{
1928 BT_DBG("%s", hdev->name);
1929}
1930
1931static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1932{
1933 BT_DBG("%s", hdev->name);
1934}
1935
1936static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1937{
1938 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1939 __u16 opcode;
1940
1941 skb_pull(skb, sizeof(*ev));
1942
1943 opcode = __le16_to_cpu(ev->opcode);
1944
1945 switch (opcode) {
1946 case HCI_OP_INQUIRY_CANCEL:
1947 hci_cc_inquiry_cancel(hdev, skb);
1948 break;
1949
1950 case HCI_OP_EXIT_PERIODIC_INQ:
1951 hci_cc_exit_periodic_inq(hdev, skb);
1952 break;
1953
1954 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1955 hci_cc_remote_name_req_cancel(hdev, skb);
1956 break;
1957
1958 case HCI_OP_ROLE_DISCOVERY:
1959 hci_cc_role_discovery(hdev, skb);
1960 break;
1961
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001962 case HCI_OP_READ_LINK_POLICY:
1963 hci_cc_read_link_policy(hdev, skb);
1964 break;
1965
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001966 case HCI_OP_WRITE_LINK_POLICY:
1967 hci_cc_write_link_policy(hdev, skb);
1968 break;
1969
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001970 case HCI_OP_READ_DEF_LINK_POLICY:
1971 hci_cc_read_def_link_policy(hdev, skb);
1972 break;
1973
1974 case HCI_OP_WRITE_DEF_LINK_POLICY:
1975 hci_cc_write_def_link_policy(hdev, skb);
1976 break;
1977
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001978 case HCI_OP_RESET:
1979 hci_cc_reset(hdev, skb);
1980 break;
1981
1982 case HCI_OP_WRITE_LOCAL_NAME:
1983 hci_cc_write_local_name(hdev, skb);
1984 break;
1985
1986 case HCI_OP_READ_LOCAL_NAME:
1987 hci_cc_read_local_name(hdev, skb);
1988 break;
1989
1990 case HCI_OP_WRITE_AUTH_ENABLE:
1991 hci_cc_write_auth_enable(hdev, skb);
1992 break;
1993
1994 case HCI_OP_WRITE_ENCRYPT_MODE:
1995 hci_cc_write_encrypt_mode(hdev, skb);
1996 break;
1997
1998 case HCI_OP_WRITE_SCAN_ENABLE:
1999 hci_cc_write_scan_enable(hdev, skb);
2000 break;
2001
2002 case HCI_OP_READ_CLASS_OF_DEV:
2003 hci_cc_read_class_of_dev(hdev, skb);
2004 break;
2005
2006 case HCI_OP_WRITE_CLASS_OF_DEV:
2007 hci_cc_write_class_of_dev(hdev, skb);
2008 break;
2009
2010 case HCI_OP_READ_VOICE_SETTING:
2011 hci_cc_read_voice_setting(hdev, skb);
2012 break;
2013
2014 case HCI_OP_WRITE_VOICE_SETTING:
2015 hci_cc_write_voice_setting(hdev, skb);
2016 break;
2017
2018 case HCI_OP_HOST_BUFFER_SIZE:
2019 hci_cc_host_buffer_size(hdev, skb);
2020 break;
2021
Marcel Holtmann333140b2008-07-14 20:13:48 +02002022 case HCI_OP_READ_SSP_MODE:
2023 hci_cc_read_ssp_mode(hdev, skb);
2024 break;
2025
2026 case HCI_OP_WRITE_SSP_MODE:
2027 hci_cc_write_ssp_mode(hdev, skb);
2028 break;
2029
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002030 case HCI_OP_READ_LOCAL_VERSION:
2031 hci_cc_read_local_version(hdev, skb);
2032 break;
2033
2034 case HCI_OP_READ_LOCAL_COMMANDS:
2035 hci_cc_read_local_commands(hdev, skb);
2036 break;
2037
2038 case HCI_OP_READ_LOCAL_FEATURES:
2039 hci_cc_read_local_features(hdev, skb);
2040 break;
2041
Andre Guedes971e3a42011-06-30 19:20:52 -03002042 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2043 hci_cc_read_local_ext_features(hdev, skb);
2044 break;
2045
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002046 case HCI_OP_READ_BUFFER_SIZE:
2047 hci_cc_read_buffer_size(hdev, skb);
2048 break;
2049
2050 case HCI_OP_READ_BD_ADDR:
2051 hci_cc_read_bd_addr(hdev, skb);
2052 break;
2053
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002054 case HCI_OP_READ_DATA_BLOCK_SIZE:
2055 hci_cc_read_data_block_size(hdev, skb);
2056 break;
2057
Johan Hedberg23bb5762010-12-21 23:01:27 +02002058 case HCI_OP_WRITE_CA_TIMEOUT:
2059 hci_cc_write_ca_timeout(hdev, skb);
2060 break;
2061
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002062 case HCI_OP_READ_FLOW_CONTROL_MODE:
2063 hci_cc_read_flow_control_mode(hdev, skb);
2064 break;
2065
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002066 case HCI_OP_READ_LOCAL_AMP_INFO:
2067 hci_cc_read_local_amp_info(hdev, skb);
2068 break;
2069
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002070 case HCI_OP_DELETE_STORED_LINK_KEY:
2071 hci_cc_delete_stored_link_key(hdev, skb);
2072 break;
2073
Johan Hedbergd5859e22011-01-25 01:19:58 +02002074 case HCI_OP_SET_EVENT_MASK:
2075 hci_cc_set_event_mask(hdev, skb);
2076 break;
2077
2078 case HCI_OP_WRITE_INQUIRY_MODE:
2079 hci_cc_write_inquiry_mode(hdev, skb);
2080 break;
2081
2082 case HCI_OP_READ_INQ_RSP_TX_POWER:
2083 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2084 break;
2085
2086 case HCI_OP_SET_EVENT_FLT:
2087 hci_cc_set_event_flt(hdev, skb);
2088 break;
2089
Johan Hedberg980e1a52011-01-22 06:10:07 +02002090 case HCI_OP_PIN_CODE_REPLY:
2091 hci_cc_pin_code_reply(hdev, skb);
2092 break;
2093
2094 case HCI_OP_PIN_CODE_NEG_REPLY:
2095 hci_cc_pin_code_neg_reply(hdev, skb);
2096 break;
2097
Szymon Jancc35938b2011-03-22 13:12:21 +01002098 case HCI_OP_READ_LOCAL_OOB_DATA:
2099 hci_cc_read_local_oob_data_reply(hdev, skb);
2100 break;
2101
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002102 case HCI_OP_LE_READ_BUFFER_SIZE:
2103 hci_cc_le_read_buffer_size(hdev, skb);
2104 break;
2105
Johan Hedberga5c29682011-02-19 12:05:57 -03002106 case HCI_OP_USER_CONFIRM_REPLY:
2107 hci_cc_user_confirm_reply(hdev, skb);
2108 break;
2109
2110 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2111 hci_cc_user_confirm_neg_reply(hdev, skb);
2112 break;
2113
Brian Gix1143d452011-11-23 08:28:34 -08002114 case HCI_OP_USER_PASSKEY_REPLY:
2115 hci_cc_user_passkey_reply(hdev, skb);
2116 break;
2117
2118 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2119 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002120
2121 case HCI_OP_LE_SET_SCAN_PARAM:
2122 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002123 break;
2124
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002125 case HCI_OP_LE_SET_SCAN_ENABLE:
2126 hci_cc_le_set_scan_enable(hdev, skb);
2127 break;
2128
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002129 case HCI_OP_LE_LTK_REPLY:
2130 hci_cc_le_ltk_reply(hdev, skb);
2131 break;
2132
2133 case HCI_OP_LE_LTK_NEG_REPLY:
2134 hci_cc_le_ltk_neg_reply(hdev, skb);
2135 break;
2136
Andre Guedesf9b49302011-06-30 19:20:53 -03002137 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2138 hci_cc_write_le_host_supported(hdev, skb);
2139 break;
2140
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002141 default:
2142 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2143 break;
2144 }
2145
Ville Tervo6bd32322011-02-16 16:32:41 +02002146 if (ev->opcode != HCI_OP_NOP)
2147 del_timer(&hdev->cmd_timer);
2148
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002149 if (ev->ncmd) {
2150 atomic_set(&hdev->cmd_cnt, 1);
2151 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002152 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002153 }
2154}
2155
2156static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2157{
2158 struct hci_ev_cmd_status *ev = (void *) skb->data;
2159 __u16 opcode;
2160
2161 skb_pull(skb, sizeof(*ev));
2162
2163 opcode = __le16_to_cpu(ev->opcode);
2164
2165 switch (opcode) {
2166 case HCI_OP_INQUIRY:
2167 hci_cs_inquiry(hdev, ev->status);
2168 break;
2169
2170 case HCI_OP_CREATE_CONN:
2171 hci_cs_create_conn(hdev, ev->status);
2172 break;
2173
2174 case HCI_OP_ADD_SCO:
2175 hci_cs_add_sco(hdev, ev->status);
2176 break;
2177
Marcel Holtmannf8558552008-07-14 20:13:49 +02002178 case HCI_OP_AUTH_REQUESTED:
2179 hci_cs_auth_requested(hdev, ev->status);
2180 break;
2181
2182 case HCI_OP_SET_CONN_ENCRYPT:
2183 hci_cs_set_conn_encrypt(hdev, ev->status);
2184 break;
2185
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002186 case HCI_OP_REMOTE_NAME_REQ:
2187 hci_cs_remote_name_req(hdev, ev->status);
2188 break;
2189
Marcel Holtmann769be972008-07-14 20:13:49 +02002190 case HCI_OP_READ_REMOTE_FEATURES:
2191 hci_cs_read_remote_features(hdev, ev->status);
2192 break;
2193
2194 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2195 hci_cs_read_remote_ext_features(hdev, ev->status);
2196 break;
2197
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002198 case HCI_OP_SETUP_SYNC_CONN:
2199 hci_cs_setup_sync_conn(hdev, ev->status);
2200 break;
2201
2202 case HCI_OP_SNIFF_MODE:
2203 hci_cs_sniff_mode(hdev, ev->status);
2204 break;
2205
2206 case HCI_OP_EXIT_SNIFF_MODE:
2207 hci_cs_exit_sniff_mode(hdev, ev->status);
2208 break;
2209
Johan Hedberg8962ee72011-01-20 12:40:27 +02002210 case HCI_OP_DISCONNECT:
2211 if (ev->status != 0)
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002212 mgmt_disconnect_failed(hdev, NULL, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002213 break;
2214
Ville Tervofcd89c02011-02-10 22:38:47 -03002215 case HCI_OP_LE_CREATE_CONN:
2216 hci_cs_le_create_conn(hdev, ev->status);
2217 break;
2218
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002219 case HCI_OP_LE_START_ENC:
2220 hci_cs_le_start_enc(hdev, ev->status);
2221 break;
2222
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002223 default:
2224 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2225 break;
2226 }
2227
Ville Tervo6bd32322011-02-16 16:32:41 +02002228 if (ev->opcode != HCI_OP_NOP)
2229 del_timer(&hdev->cmd_timer);
2230
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002231 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002232 atomic_set(&hdev->cmd_cnt, 1);
2233 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002234 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002235 }
2236}
2237
2238static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2239{
2240 struct hci_ev_role_change *ev = (void *) skb->data;
2241 struct hci_conn *conn;
2242
2243 BT_DBG("%s status %d", hdev->name, ev->status);
2244
2245 hci_dev_lock(hdev);
2246
2247 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2248 if (conn) {
2249 if (!ev->status) {
2250 if (ev->role)
2251 conn->link_mode &= ~HCI_LM_MASTER;
2252 else
2253 conn->link_mode |= HCI_LM_MASTER;
2254 }
2255
2256 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
2257
2258 hci_role_switch_cfm(conn, ev->status, ev->role);
2259 }
2260
2261 hci_dev_unlock(hdev);
2262}
2263
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2265{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002266 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002267 int i;
2268
2269 skb_pull(skb, sizeof(*ev));
2270
2271 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2272
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002273 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2274 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2275 return;
2276 }
2277
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278 if (skb->len < ev->num_hndl * 4) {
2279 BT_DBG("%s bad parameters", hdev->name);
2280 return;
2281 }
2282
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002283 for (i = 0; i < ev->num_hndl; i++) {
2284 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285 struct hci_conn *conn;
2286 __u16 handle, count;
2287
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002288 handle = __le16_to_cpu(info->handle);
2289 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002290
2291 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002292 if (!conn)
2293 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002295 conn->sent -= count;
2296
2297 switch (conn->type) {
2298 case ACL_LINK:
2299 hdev->acl_cnt += count;
2300 if (hdev->acl_cnt > hdev->acl_pkts)
2301 hdev->acl_cnt = hdev->acl_pkts;
2302 break;
2303
2304 case LE_LINK:
2305 if (hdev->le_pkts) {
2306 hdev->le_cnt += count;
2307 if (hdev->le_cnt > hdev->le_pkts)
2308 hdev->le_cnt = hdev->le_pkts;
2309 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002310 hdev->acl_cnt += count;
2311 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312 hdev->acl_cnt = hdev->acl_pkts;
2313 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002314 break;
2315
2316 case SCO_LINK:
2317 hdev->sco_cnt += count;
2318 if (hdev->sco_cnt > hdev->sco_pkts)
2319 hdev->sco_cnt = hdev->sco_pkts;
2320 break;
2321
2322 default:
2323 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2324 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325 }
2326 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002327
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002328 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329}
2330
Marcel Holtmann04837f62006-07-03 10:02:33 +02002331static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002333 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002334 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335
2336 BT_DBG("%s status %d", hdev->name, ev->status);
2337
2338 hci_dev_lock(hdev);
2339
Marcel Holtmann04837f62006-07-03 10:02:33 +02002340 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2341 if (conn) {
2342 conn->mode = ev->mode;
2343 conn->interval = __le16_to_cpu(ev->interval);
2344
2345 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
2346 if (conn->mode == HCI_CM_ACTIVE)
2347 conn->power_save = 1;
2348 else
2349 conn->power_save = 0;
2350 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002351
2352 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
2353 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002354 }
2355
2356 hci_dev_unlock(hdev);
2357}
2358
Linus Torvalds1da177e2005-04-16 15:20:36 -07002359static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2360{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002361 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2362 struct hci_conn *conn;
2363
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002364 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002365
2366 hci_dev_lock(hdev);
2367
2368 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002369 if (!conn)
2370 goto unlock;
2371
2372 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002373 hci_conn_hold(conn);
2374 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2375 hci_conn_put(conn);
2376 }
2377
Johan Hedberg03b555e2011-01-04 15:40:05 +02002378 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
2379 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2380 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg582fbe92011-04-28 11:28:58 -07002381 else if (test_bit(HCI_MGMT, &hdev->flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002382 u8 secure;
2383
2384 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2385 secure = 1;
2386 else
2387 secure = 0;
2388
Johan Hedberg744cf192011-11-08 20:40:14 +02002389 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002390 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002391
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002392unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002393 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394}
2395
Linus Torvalds1da177e2005-04-16 15:20:36 -07002396static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2397{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002398 struct hci_ev_link_key_req *ev = (void *) skb->data;
2399 struct hci_cp_link_key_reply cp;
2400 struct hci_conn *conn;
2401 struct link_key *key;
2402
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002403 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002404
2405 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
2406 return;
2407
2408 hci_dev_lock(hdev);
2409
2410 key = hci_find_link_key(hdev, &ev->bdaddr);
2411 if (!key) {
2412 BT_DBG("%s link key not found for %s", hdev->name,
2413 batostr(&ev->bdaddr));
2414 goto not_found;
2415 }
2416
2417 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2418 batostr(&ev->bdaddr));
2419
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002420 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) &&
2421 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002422 BT_DBG("%s ignoring debug key", hdev->name);
2423 goto not_found;
2424 }
2425
2426 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002427 if (conn) {
2428 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2429 conn->auth_type != 0xff &&
2430 (conn->auth_type & 0x01)) {
2431 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2432 goto not_found;
2433 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002434
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002435 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2436 conn->pending_sec_level == BT_SECURITY_HIGH) {
2437 BT_DBG("%s ignoring key unauthenticated for high \
2438 security", hdev->name);
2439 goto not_found;
2440 }
2441
2442 conn->key_type = key->type;
2443 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002444 }
2445
2446 bacpy(&cp.bdaddr, &ev->bdaddr);
2447 memcpy(cp.link_key, key->val, 16);
2448
2449 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2450
2451 hci_dev_unlock(hdev);
2452
2453 return;
2454
2455not_found:
2456 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2457 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458}
2459
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2461{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002462 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2463 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002464 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002465
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002466 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002467
2468 hci_dev_lock(hdev);
2469
2470 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2471 if (conn) {
2472 hci_conn_hold(conn);
2473 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002474 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002475
2476 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2477 conn->key_type = ev->key_type;
2478
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002479 hci_conn_put(conn);
2480 }
2481
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002482 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002483 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002484 ev->key_type, pin_len);
2485
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002486 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487}
2488
Marcel Holtmann04837f62006-07-03 10:02:33 +02002489static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2490{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002491 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002492 struct hci_conn *conn;
2493
2494 BT_DBG("%s status %d", hdev->name, ev->status);
2495
2496 hci_dev_lock(hdev);
2497
2498 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 if (conn && !ev->status) {
2500 struct inquiry_entry *ie;
2501
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002502 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2503 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504 ie->data.clock_offset = ev->clock_offset;
2505 ie->timestamp = jiffies;
2506 }
2507 }
2508
2509 hci_dev_unlock(hdev);
2510}
2511
Marcel Holtmanna8746412008-07-14 20:13:46 +02002512static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2513{
2514 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2515 struct hci_conn *conn;
2516
2517 BT_DBG("%s status %d", hdev->name, ev->status);
2518
2519 hci_dev_lock(hdev);
2520
2521 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2522 if (conn && !ev->status)
2523 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2524
2525 hci_dev_unlock(hdev);
2526}
2527
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002528static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2529{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002530 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002531 struct inquiry_entry *ie;
2532
2533 BT_DBG("%s", hdev->name);
2534
2535 hci_dev_lock(hdev);
2536
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002537 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2538 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002539 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2540 ie->timestamp = jiffies;
2541 }
2542
2543 hci_dev_unlock(hdev);
2544}
2545
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002546static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2547{
2548 struct inquiry_data data;
2549 int num_rsp = *((__u8 *) skb->data);
2550
2551 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2552
2553 if (!num_rsp)
2554 return;
2555
2556 hci_dev_lock(hdev);
2557
2558 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002559 struct inquiry_info_with_rssi_and_pscan_mode *info;
2560 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002561
Johan Hedberge17acd42011-03-30 23:57:16 +03002562 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002563 bacpy(&data.bdaddr, &info->bdaddr);
2564 data.pscan_rep_mode = info->pscan_rep_mode;
2565 data.pscan_period_mode = info->pscan_period_mode;
2566 data.pscan_mode = info->pscan_mode;
2567 memcpy(data.dev_class, info->dev_class, 3);
2568 data.clock_offset = info->clock_offset;
2569 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002570 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002571 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002572 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002573 info->dev_class, info->rssi,
2574 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002575 }
2576 } else {
2577 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2578
Johan Hedberge17acd42011-03-30 23:57:16 +03002579 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002580 bacpy(&data.bdaddr, &info->bdaddr);
2581 data.pscan_rep_mode = info->pscan_rep_mode;
2582 data.pscan_period_mode = info->pscan_period_mode;
2583 data.pscan_mode = 0x00;
2584 memcpy(data.dev_class, info->dev_class, 3);
2585 data.clock_offset = info->clock_offset;
2586 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002587 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002588 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002589 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002590 info->dev_class, info->rssi,
2591 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002592 }
2593 }
2594
2595 hci_dev_unlock(hdev);
2596}
2597
2598static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2599{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002600 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2601 struct hci_conn *conn;
2602
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002603 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002604
Marcel Holtmann41a96212008-07-14 20:13:48 +02002605 hci_dev_lock(hdev);
2606
2607 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002608 if (!conn)
2609 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002610
Johan Hedbergccd556f2010-11-10 17:11:51 +02002611 if (!ev->status && ev->page == 0x01) {
2612 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002613
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002614 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2615 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002616 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002617
Johan Hedbergccd556f2010-11-10 17:11:51 +02002618 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002619 }
2620
Johan Hedbergccd556f2010-11-10 17:11:51 +02002621 if (conn->state != BT_CONFIG)
2622 goto unlock;
2623
Johan Hedberg127178d2010-11-18 22:22:29 +02002624 if (!ev->status) {
2625 struct hci_cp_remote_name_req cp;
2626 memset(&cp, 0, sizeof(cp));
2627 bacpy(&cp.bdaddr, &conn->dst);
2628 cp.pscan_rep_mode = 0x02;
2629 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2630 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002631
Johan Hedberg127178d2010-11-18 22:22:29 +02002632 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002633 conn->state = BT_CONNECTED;
2634 hci_proto_connect_cfm(conn, ev->status);
2635 hci_conn_put(conn);
2636 }
2637
2638unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002639 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002640}
2641
2642static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2643{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002644 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2645 struct hci_conn *conn;
2646
2647 BT_DBG("%s status %d", hdev->name, ev->status);
2648
2649 hci_dev_lock(hdev);
2650
2651 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002652 if (!conn) {
2653 if (ev->link_type == ESCO_LINK)
2654 goto unlock;
2655
2656 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2657 if (!conn)
2658 goto unlock;
2659
2660 conn->type = SCO_LINK;
2661 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002662
Marcel Holtmann732547f2009-04-19 19:14:14 +02002663 switch (ev->status) {
2664 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002665 conn->handle = __le16_to_cpu(ev->handle);
2666 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002667
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002668 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002669 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002670 break;
2671
Stephen Coe705e5712010-02-16 11:29:44 -05002672 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002673 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002674 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002675 case 0x1f: /* Unspecified error */
2676 if (conn->out && conn->attempt < 2) {
2677 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2678 (hdev->esco_type & EDR_ESCO_MASK);
2679 hci_setup_sync(conn, conn->link->handle);
2680 goto unlock;
2681 }
2682 /* fall through */
2683
2684 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002685 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002686 break;
2687 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002688
2689 hci_proto_connect_cfm(conn, ev->status);
2690 if (ev->status)
2691 hci_conn_del(conn);
2692
2693unlock:
2694 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002695}
2696
2697static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2698{
2699 BT_DBG("%s", hdev->name);
2700}
2701
Marcel Holtmann04837f62006-07-03 10:02:33 +02002702static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2703{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002704 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002705
2706 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002707}
2708
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002709static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2710{
2711 struct inquiry_data data;
2712 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2713 int num_rsp = *((__u8 *) skb->data);
2714
2715 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2716
2717 if (!num_rsp)
2718 return;
2719
2720 hci_dev_lock(hdev);
2721
Johan Hedberge17acd42011-03-30 23:57:16 +03002722 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002723 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002724 data.pscan_rep_mode = info->pscan_rep_mode;
2725 data.pscan_period_mode = info->pscan_period_mode;
2726 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002727 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002728 data.clock_offset = info->clock_offset;
2729 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002730 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002731 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg48264f02011-11-09 13:58:58 +02002732 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg4c659c32011-11-07 23:13:39 +02002733 info->dev_class, info->rssi, info->data);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002734 }
2735
2736 hci_dev_unlock(hdev);
2737}
2738
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002739static inline u8 hci_get_auth_req(struct hci_conn *conn)
2740{
2741 /* If remote requests dedicated bonding follow that lead */
2742 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2743 /* If both remote and local IO capabilities allow MITM
2744 * protection then require it, otherwise don't */
2745 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2746 return 0x02;
2747 else
2748 return 0x03;
2749 }
2750
2751 /* If remote requests no-bonding follow that lead */
2752 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002753 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002754
2755 return conn->auth_type;
2756}
2757
Marcel Holtmann04936842008-07-14 20:13:48 +02002758static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2759{
2760 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2761 struct hci_conn *conn;
2762
2763 BT_DBG("%s", hdev->name);
2764
2765 hci_dev_lock(hdev);
2766
2767 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002768 if (!conn)
2769 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002770
Johan Hedberg03b555e2011-01-04 15:40:05 +02002771 hci_conn_hold(conn);
2772
2773 if (!test_bit(HCI_MGMT, &hdev->flags))
2774 goto unlock;
2775
2776 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
2777 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002778 struct hci_cp_io_capability_reply cp;
2779
2780 bacpy(&cp.bdaddr, &ev->bdaddr);
2781 cp.capability = conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07002782 conn->auth_type = hci_get_auth_req(conn);
2783 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002784
Szymon Jancce85ee12011-03-22 13:12:23 +01002785 if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
2786 hci_find_remote_oob_data(hdev, &conn->dst))
2787 cp.oob_data = 0x01;
2788 else
2789 cp.oob_data = 0x00;
2790
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002791 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2792 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002793 } else {
2794 struct hci_cp_io_capability_neg_reply cp;
2795
2796 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002797 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02002798
2799 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2800 sizeof(cp), &cp);
2801 }
2802
2803unlock:
2804 hci_dev_unlock(hdev);
2805}
2806
2807static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2808{
2809 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2810 struct hci_conn *conn;
2811
2812 BT_DBG("%s", hdev->name);
2813
2814 hci_dev_lock(hdev);
2815
2816 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2817 if (!conn)
2818 goto unlock;
2819
Johan Hedberg03b555e2011-01-04 15:40:05 +02002820 conn->remote_cap = ev->capability;
2821 conn->remote_oob = ev->oob_data;
2822 conn->remote_auth = ev->authentication;
2823
2824unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002825 hci_dev_unlock(hdev);
2826}
2827
Johan Hedberga5c29682011-02-19 12:05:57 -03002828static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2829 struct sk_buff *skb)
2830{
2831 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002832 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07002833 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03002834
2835 BT_DBG("%s", hdev->name);
2836
2837 hci_dev_lock(hdev);
2838
Johan Hedberg7a828902011-04-28 11:28:53 -07002839 if (!test_bit(HCI_MGMT, &hdev->flags))
2840 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03002841
Johan Hedberg7a828902011-04-28 11:28:53 -07002842 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2843 if (!conn)
2844 goto unlock;
2845
2846 loc_mitm = (conn->auth_type & 0x01);
2847 rem_mitm = (conn->remote_auth & 0x01);
2848
2849 /* If we require MITM but the remote device can't provide that
2850 * (it has NoInputNoOutput) then reject the confirmation
2851 * request. The only exception is when we're dedicated bonding
2852 * initiators (connect_cfm_cb set) since then we always have the MITM
2853 * bit set. */
2854 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
2855 BT_DBG("Rejecting request: remote device can't provide MITM");
2856 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
2857 sizeof(ev->bdaddr), &ev->bdaddr);
2858 goto unlock;
2859 }
2860
2861 /* If no side requires MITM protection; auto-accept */
2862 if ((!loc_mitm || conn->remote_cap == 0x03) &&
2863 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002864
2865 /* If we're not the initiators request authorization to
2866 * proceed from user space (mgmt_user_confirm with
2867 * confirm_hint set to 1). */
2868 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
2869 BT_DBG("Confirming auto-accept as acceptor");
2870 confirm_hint = 1;
2871 goto confirm;
2872 }
2873
Johan Hedberg9f616562011-04-28 11:28:54 -07002874 BT_DBG("Auto-accept of user confirmation with %ums delay",
2875 hdev->auto_accept_delay);
2876
2877 if (hdev->auto_accept_delay > 0) {
2878 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
2879 mod_timer(&conn->auto_accept_timer, jiffies + delay);
2880 goto unlock;
2881 }
2882
Johan Hedberg7a828902011-04-28 11:28:53 -07002883 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
2884 sizeof(ev->bdaddr), &ev->bdaddr);
2885 goto unlock;
2886 }
2887
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002888confirm:
Johan Hedberg744cf192011-11-08 20:40:14 +02002889 mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002890 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07002891
2892unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03002893 hci_dev_unlock(hdev);
2894}
2895
Brian Gix1143d452011-11-23 08:28:34 -08002896static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
2897 struct sk_buff *skb)
2898{
2899 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
2900
2901 BT_DBG("%s", hdev->name);
2902
2903 hci_dev_lock(hdev);
2904
2905 if (test_bit(HCI_MGMT, &hdev->flags))
2906 mgmt_user_passkey_request(hdev, &ev->bdaddr);
2907
2908 hci_dev_unlock(hdev);
2909}
2910
Marcel Holtmann04936842008-07-14 20:13:48 +02002911static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2912{
2913 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
2914 struct hci_conn *conn;
2915
2916 BT_DBG("%s", hdev->name);
2917
2918 hci_dev_lock(hdev);
2919
2920 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03002921 if (!conn)
2922 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002923
Johan Hedberg2a611692011-02-19 12:06:00 -03002924 /* To avoid duplicate auth_failed events to user space we check
2925 * the HCI_CONN_AUTH_PEND flag which will be set if we
2926 * initiated the authentication. A traditional auth_complete
2927 * event gets always produced as initiator and is also mapped to
2928 * the mgmt_auth_failed event */
2929 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
Johan Hedberg744cf192011-11-08 20:40:14 +02002930 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03002931
2932 hci_conn_put(conn);
2933
2934unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002935 hci_dev_unlock(hdev);
2936}
2937
Marcel Holtmann41a96212008-07-14 20:13:48 +02002938static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2939{
2940 struct hci_ev_remote_host_features *ev = (void *) skb->data;
2941 struct inquiry_entry *ie;
2942
2943 BT_DBG("%s", hdev->name);
2944
2945 hci_dev_lock(hdev);
2946
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002947 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2948 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02002949 ie->data.ssp_mode = (ev->features[0] & 0x01);
2950
2951 hci_dev_unlock(hdev);
2952}
2953
Szymon Janc2763eda2011-03-22 13:12:22 +01002954static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
2955 struct sk_buff *skb)
2956{
2957 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
2958 struct oob_data *data;
2959
2960 BT_DBG("%s", hdev->name);
2961
2962 hci_dev_lock(hdev);
2963
Szymon Jance1ba1f12011-04-06 13:01:59 +02002964 if (!test_bit(HCI_MGMT, &hdev->flags))
2965 goto unlock;
2966
Szymon Janc2763eda2011-03-22 13:12:22 +01002967 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
2968 if (data) {
2969 struct hci_cp_remote_oob_data_reply cp;
2970
2971 bacpy(&cp.bdaddr, &ev->bdaddr);
2972 memcpy(cp.hash, data->hash, sizeof(cp.hash));
2973 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
2974
2975 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
2976 &cp);
2977 } else {
2978 struct hci_cp_remote_oob_data_neg_reply cp;
2979
2980 bacpy(&cp.bdaddr, &ev->bdaddr);
2981 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
2982 &cp);
2983 }
2984
Szymon Jance1ba1f12011-04-06 13:01:59 +02002985unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01002986 hci_dev_unlock(hdev);
2987}
2988
Ville Tervofcd89c02011-02-10 22:38:47 -03002989static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2990{
2991 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2992 struct hci_conn *conn;
2993
2994 BT_DBG("%s status %d", hdev->name, ev->status);
2995
2996 hci_dev_lock(hdev);
2997
2998 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03002999 if (!conn) {
3000 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3001 if (!conn) {
3002 BT_ERR("No memory for new connection");
3003 hci_dev_unlock(hdev);
3004 return;
3005 }
Andre Guedes29b79882011-05-31 14:20:54 -03003006
3007 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003008 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003009
3010 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003011 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3012 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003013 hci_proto_connect_cfm(conn, ev->status);
3014 conn->state = BT_CLOSED;
3015 hci_conn_del(conn);
3016 goto unlock;
3017 }
3018
Johan Hedberg48264f02011-11-09 13:58:58 +02003019 mgmt_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003020
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003021 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003022 conn->handle = __le16_to_cpu(ev->handle);
3023 conn->state = BT_CONNECTED;
3024
3025 hci_conn_hold_device(conn);
3026 hci_conn_add_sysfs(conn);
3027
3028 hci_proto_connect_cfm(conn, ev->status);
3029
3030unlock:
3031 hci_dev_unlock(hdev);
3032}
3033
Andre Guedes9aa04c92011-05-26 16:23:51 -03003034static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3035 struct sk_buff *skb)
3036{
Andre Guedese95beb42011-09-26 20:48:35 -03003037 u8 num_reports = skb->data[0];
3038 void *ptr = &skb->data[1];
Andre Guedes9aa04c92011-05-26 16:23:51 -03003039
3040 hci_dev_lock(hdev);
3041
Andre Guedese95beb42011-09-26 20:48:35 -03003042 while (num_reports--) {
3043 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003044
Andre Guedes9aa04c92011-05-26 16:23:51 -03003045 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003046
3047 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003048 }
3049
3050 hci_dev_unlock(hdev);
3051}
3052
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003053static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3054 struct sk_buff *skb)
3055{
3056 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3057 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003058 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003059 struct hci_conn *conn;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003060 struct link_key *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003061
3062 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3063
3064 hci_dev_lock(hdev);
3065
3066 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003067 if (conn == NULL)
3068 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003069
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003070 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3071 if (ltk == NULL)
3072 goto not_found;
3073
3074 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003075 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes726b4ff2011-07-08 18:31:45 -03003076 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003077
3078 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3079
3080 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003081
3082 return;
3083
3084not_found:
3085 neg.handle = ev->handle;
3086 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3087 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003088}
3089
Ville Tervofcd89c02011-02-10 22:38:47 -03003090static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3091{
3092 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3093
3094 skb_pull(skb, sizeof(*le_ev));
3095
3096 switch (le_ev->subevent) {
3097 case HCI_EV_LE_CONN_COMPLETE:
3098 hci_le_conn_complete_evt(hdev, skb);
3099 break;
3100
Andre Guedes9aa04c92011-05-26 16:23:51 -03003101 case HCI_EV_LE_ADVERTISING_REPORT:
3102 hci_le_adv_report_evt(hdev, skb);
3103 break;
3104
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003105 case HCI_EV_LE_LTK_REQ:
3106 hci_le_ltk_request_evt(hdev, skb);
3107 break;
3108
Ville Tervofcd89c02011-02-10 22:38:47 -03003109 default:
3110 break;
3111 }
3112}
3113
Linus Torvalds1da177e2005-04-16 15:20:36 -07003114void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3115{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003116 struct hci_event_hdr *hdr = (void *) skb->data;
3117 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003118
3119 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3120
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003121 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003122 case HCI_EV_INQUIRY_COMPLETE:
3123 hci_inquiry_complete_evt(hdev, skb);
3124 break;
3125
3126 case HCI_EV_INQUIRY_RESULT:
3127 hci_inquiry_result_evt(hdev, skb);
3128 break;
3129
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003130 case HCI_EV_CONN_COMPLETE:
3131 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003132 break;
3133
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134 case HCI_EV_CONN_REQUEST:
3135 hci_conn_request_evt(hdev, skb);
3136 break;
3137
Linus Torvalds1da177e2005-04-16 15:20:36 -07003138 case HCI_EV_DISCONN_COMPLETE:
3139 hci_disconn_complete_evt(hdev, skb);
3140 break;
3141
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142 case HCI_EV_AUTH_COMPLETE:
3143 hci_auth_complete_evt(hdev, skb);
3144 break;
3145
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003146 case HCI_EV_REMOTE_NAME:
3147 hci_remote_name_evt(hdev, skb);
3148 break;
3149
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150 case HCI_EV_ENCRYPT_CHANGE:
3151 hci_encrypt_change_evt(hdev, skb);
3152 break;
3153
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003154 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3155 hci_change_link_key_complete_evt(hdev, skb);
3156 break;
3157
3158 case HCI_EV_REMOTE_FEATURES:
3159 hci_remote_features_evt(hdev, skb);
3160 break;
3161
3162 case HCI_EV_REMOTE_VERSION:
3163 hci_remote_version_evt(hdev, skb);
3164 break;
3165
3166 case HCI_EV_QOS_SETUP_COMPLETE:
3167 hci_qos_setup_complete_evt(hdev, skb);
3168 break;
3169
3170 case HCI_EV_CMD_COMPLETE:
3171 hci_cmd_complete_evt(hdev, skb);
3172 break;
3173
3174 case HCI_EV_CMD_STATUS:
3175 hci_cmd_status_evt(hdev, skb);
3176 break;
3177
3178 case HCI_EV_ROLE_CHANGE:
3179 hci_role_change_evt(hdev, skb);
3180 break;
3181
3182 case HCI_EV_NUM_COMP_PKTS:
3183 hci_num_comp_pkts_evt(hdev, skb);
3184 break;
3185
3186 case HCI_EV_MODE_CHANGE:
3187 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003188 break;
3189
3190 case HCI_EV_PIN_CODE_REQ:
3191 hci_pin_code_request_evt(hdev, skb);
3192 break;
3193
3194 case HCI_EV_LINK_KEY_REQ:
3195 hci_link_key_request_evt(hdev, skb);
3196 break;
3197
3198 case HCI_EV_LINK_KEY_NOTIFY:
3199 hci_link_key_notify_evt(hdev, skb);
3200 break;
3201
3202 case HCI_EV_CLOCK_OFFSET:
3203 hci_clock_offset_evt(hdev, skb);
3204 break;
3205
Marcel Holtmanna8746412008-07-14 20:13:46 +02003206 case HCI_EV_PKT_TYPE_CHANGE:
3207 hci_pkt_type_change_evt(hdev, skb);
3208 break;
3209
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003210 case HCI_EV_PSCAN_REP_MODE:
3211 hci_pscan_rep_mode_evt(hdev, skb);
3212 break;
3213
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003214 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3215 hci_inquiry_result_with_rssi_evt(hdev, skb);
3216 break;
3217
3218 case HCI_EV_REMOTE_EXT_FEATURES:
3219 hci_remote_ext_features_evt(hdev, skb);
3220 break;
3221
3222 case HCI_EV_SYNC_CONN_COMPLETE:
3223 hci_sync_conn_complete_evt(hdev, skb);
3224 break;
3225
3226 case HCI_EV_SYNC_CONN_CHANGED:
3227 hci_sync_conn_changed_evt(hdev, skb);
3228 break;
3229
Marcel Holtmann04837f62006-07-03 10:02:33 +02003230 case HCI_EV_SNIFF_SUBRATE:
3231 hci_sniff_subrate_evt(hdev, skb);
3232 break;
3233
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003234 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3235 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003236 break;
3237
Marcel Holtmann04936842008-07-14 20:13:48 +02003238 case HCI_EV_IO_CAPA_REQUEST:
3239 hci_io_capa_request_evt(hdev, skb);
3240 break;
3241
Johan Hedberg03b555e2011-01-04 15:40:05 +02003242 case HCI_EV_IO_CAPA_REPLY:
3243 hci_io_capa_reply_evt(hdev, skb);
3244 break;
3245
Johan Hedberga5c29682011-02-19 12:05:57 -03003246 case HCI_EV_USER_CONFIRM_REQUEST:
3247 hci_user_confirm_request_evt(hdev, skb);
3248 break;
3249
Brian Gix1143d452011-11-23 08:28:34 -08003250 case HCI_EV_USER_PASSKEY_REQUEST:
3251 hci_user_passkey_request_evt(hdev, skb);
3252 break;
3253
Marcel Holtmann04936842008-07-14 20:13:48 +02003254 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3255 hci_simple_pair_complete_evt(hdev, skb);
3256 break;
3257
Marcel Holtmann41a96212008-07-14 20:13:48 +02003258 case HCI_EV_REMOTE_HOST_FEATURES:
3259 hci_remote_host_features_evt(hdev, skb);
3260 break;
3261
Ville Tervofcd89c02011-02-10 22:38:47 -03003262 case HCI_EV_LE_META:
3263 hci_le_meta_evt(hdev, skb);
3264 break;
3265
Szymon Janc2763eda2011-03-22 13:12:22 +01003266 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3267 hci_remote_oob_data_request_evt(hdev, skb);
3268 break;
3269
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003270 default:
3271 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003272 break;
3273 }
3274
3275 kfree_skb(skb);
3276 hdev->stat.evt_rx++;
3277}
3278
3279/* Generate internal stack event */
3280void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3281{
3282 struct hci_event_hdr *hdr;
3283 struct hci_ev_stack_internal *ev;
3284 struct sk_buff *skb;
3285
3286 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3287 if (!skb)
3288 return;
3289
3290 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3291 hdr->evt = HCI_EV_STACK_INTERNAL;
3292 hdr->plen = sizeof(*ev) + dlen;
3293
3294 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3295 ev->type = type;
3296 memcpy(ev->data, data, dlen);
3297
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003298 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003299 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003300
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003301 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003302 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003303 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003304 kfree_skb(skb);
3305}
Andre Guedese6100a22011-06-30 19:20:54 -03003306
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003307module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003308MODULE_PARM_DESC(enable_le, "Enable LE support");