blob: 3d1eef0df2a315f654f1bfa9b0587175e803f03c [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <net/sock.h>
39
40#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020041#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <asm/unaligned.h>
43
44#include <net/bluetooth/bluetooth.h>
45#include <net/bluetooth/hci_core.h>
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047/* Handle HCI Event packets */
48
Marcel Holtmanna9de9242007-10-20 13:33:56 +020049static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070050{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020051 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
Marcel Holtmanna9de9242007-10-20 13:33:56 +020053 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Andre Guedese6d465c2011-11-09 17:14:26 -030055 if (status) {
56 hci_dev_lock(hdev);
57 mgmt_stop_discovery_failed(hdev, status);
58 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020059 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030060 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
Andre Guedes89352e72011-11-04 14:16:53 -030062 clear_bit(HCI_INQUIRY, &hdev->flags);
63
Johan Hedberg56e5cb82011-11-08 20:40:16 +020064 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020065 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020066 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010067
Johan Hedberg23bb5762010-12-21 23:01:27 +020068 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010069
Marcel Holtmanna9de9242007-10-20 13:33:56 +020070 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070071}
72
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020075 __u8 status = *((__u8 *) skb->data);
76
77 BT_DBG("%s status 0x%x", hdev->name, status);
78
79 if (status)
80 return;
81
Marcel Holtmanna9de9242007-10-20 13:33:56 +020082 hci_conn_check_pending(hdev);
83}
84
85static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
86{
87 BT_DBG("%s", hdev->name);
88}
89
90static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
91{
92 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 if (rp->status)
98 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200102 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
103 if (conn) {
104 if (rp->role)
105 conn->link_mode &= ~HCI_LM_MASTER;
106 else
107 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200109
110 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111}
112
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200113static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
114{
115 struct hci_rp_read_link_policy *rp = (void *) skb->data;
116 struct hci_conn *conn;
117
118 BT_DBG("%s status 0x%x", hdev->name, rp->status);
119
120 if (rp->status)
121 return;
122
123 hci_dev_lock(hdev);
124
125 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
126 if (conn)
127 conn->link_policy = __le16_to_cpu(rp->policy);
128
129 hci_dev_unlock(hdev);
130}
131
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200132static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200134 struct hci_rp_write_link_policy *rp = (void *) skb->data;
135 struct hci_conn *conn;
136 void *sent;
137
138 BT_DBG("%s status 0x%x", hdev->name, rp->status);
139
140 if (rp->status)
141 return;
142
143 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
144 if (!sent)
145 return;
146
147 hci_dev_lock(hdev);
148
149 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200150 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700151 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200152
153 hci_dev_unlock(hdev);
154}
155
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200156static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
157{
158 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
159
160 BT_DBG("%s status 0x%x", hdev->name, rp->status);
161
162 if (rp->status)
163 return;
164
165 hdev->link_policy = __le16_to_cpu(rp->policy);
166}
167
168static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
169{
170 __u8 status = *((__u8 *) skb->data);
171 void *sent;
172
173 BT_DBG("%s status 0x%x", hdev->name, status);
174
175 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
176 if (!sent)
177 return;
178
179 if (!status)
180 hdev->link_policy = get_unaligned_le16(sent);
181
Johan Hedberg23bb5762010-12-21 23:01:27 +0200182 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200183}
184
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200185static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
186{
187 __u8 status = *((__u8 *) skb->data);
188
189 BT_DBG("%s status 0x%x", hdev->name, status);
190
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300191 clear_bit(HCI_RESET, &hdev->flags);
192
Johan Hedberg23bb5762010-12-21 23:01:27 +0200193 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300194
Johan Hedberga297e972012-02-21 17:55:47 +0200195 /* Reset all non-persistent flags */
196 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN));
Andre Guedes69775ff2012-02-23 16:50:05 +0200197
198 hdev->discovery.state = DISCOVERY_STOPPED;
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 Hedbergf51d5b22012-02-22 18:17:32 +0200214 if (test_bit(HCI_MGMT, &hdev->dev_flags))
215 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200216 else if (!status)
217 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200218
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200219 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200220}
221
222static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
223{
224 struct hci_rp_read_local_name *rp = (void *) skb->data;
225
226 BT_DBG("%s status 0x%x", hdev->name, rp->status);
227
228 if (rp->status)
229 return;
230
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200231 if (test_bit(HCI_SETUP, &hdev->dev_flags))
232 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 Hedberg33ef95e2012-02-16 23:56:27 +0200255 if (test_bit(HCI_MGMT, &hdev->dev_flags))
256 mgmt_auth_enable_complete(hdev, status);
257
Johan Hedberg23bb5762010-12-21 23:01:27 +0200258 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200259}
260
261static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
262{
263 __u8 status = *((__u8 *) skb->data);
264 void *sent;
265
266 BT_DBG("%s status 0x%x", hdev->name, status);
267
268 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
269 if (!sent)
270 return;
271
272 if (!status) {
273 __u8 param = *((__u8 *) sent);
274
275 if (param)
276 set_bit(HCI_ENCRYPT, &hdev->flags);
277 else
278 clear_bit(HCI_ENCRYPT, &hdev->flags);
279 }
280
Johan Hedberg23bb5762010-12-21 23:01:27 +0200281 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200282}
283
284static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
285{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200286 __u8 param, status = *((__u8 *) skb->data);
287 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200288 void *sent;
289
290 BT_DBG("%s status 0x%x", hdev->name, status);
291
292 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
293 if (!sent)
294 return;
295
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200296 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200297
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200298 hci_dev_lock(hdev);
299
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200300 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200301 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200302 hdev->discov_timeout = 0;
303 goto done;
304 }
305
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200306 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
307 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200308
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200309 if (param & SCAN_INQUIRY) {
310 set_bit(HCI_ISCAN, &hdev->flags);
311 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200312 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200313 if (hdev->discov_timeout > 0) {
314 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
315 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
316 to);
317 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200318 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200319 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200320
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200321 if (param & SCAN_PAGE) {
322 set_bit(HCI_PSCAN, &hdev->flags);
323 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200324 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200325 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327
328done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200329 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200330 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200331}
332
333static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
334{
335 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
336
337 BT_DBG("%s status 0x%x", hdev->name, rp->status);
338
339 if (rp->status)
340 return;
341
342 memcpy(hdev->dev_class, rp->dev_class, 3);
343
344 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
345 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
346}
347
348static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
349{
350 __u8 status = *((__u8 *) skb->data);
351 void *sent;
352
353 BT_DBG("%s status 0x%x", hdev->name, status);
354
355 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
356 if (!sent)
357 return;
358
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100359 hci_dev_lock(hdev);
360
361 if (status == 0)
362 memcpy(hdev->dev_class, sent, 3);
363
364 if (test_bit(HCI_MGMT, &hdev->dev_flags))
365 mgmt_set_class_of_dev_complete(hdev, sent, status);
366
367 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200368}
369
370static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
371{
372 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200374
375 BT_DBG("%s status 0x%x", hdev->name, rp->status);
376
377 if (rp->status)
378 return;
379
380 setting = __le16_to_cpu(rp->voice_setting);
381
Marcel Holtmannf383f272008-07-14 20:13:47 +0200382 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200383 return;
384
385 hdev->voice_setting = setting;
386
387 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
388
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200389 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200390 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200391}
392
393static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
394{
395 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200396 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 void *sent;
398
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200399 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
Marcel Holtmannf383f272008-07-14 20:13:47 +0200401 if (status)
402 return;
403
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200404 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
405 if (!sent)
406 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 if (hdev->voice_setting == setting)
411 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
Marcel Holtmannf383f272008-07-14 20:13:47 +0200413 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Marcel Holtmannf383f272008-07-14 20:13:47 +0200415 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
416
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200417 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200418 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419}
420
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200421static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200423 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200425 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
Johan Hedberg23bb5762010-12-21 23:01:27 +0200427 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428}
429
Marcel Holtmann333140b2008-07-14 20:13:48 +0200430static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
431{
432 __u8 status = *((__u8 *) skb->data);
433 void *sent;
434
435 BT_DBG("%s status 0x%x", hdev->name, status);
436
Marcel Holtmann333140b2008-07-14 20:13:48 +0200437 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
438 if (!sent)
439 return;
440
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200441 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200442 mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status);
443 else if (!status) {
444 if (*((u8 *) sent))
445 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
446 else
447 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
448 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200449}
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
Johan Hedberg06199cf2012-02-22 16:37:11 +0200549 if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
Andre Guedese6100a22011-06-30 19:20:54 -0300550 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 Emeltchenkoe61ef4992011-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
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200567 if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
568 test_bit(HCI_MGMT, &hdev->dev_flags)) {
569 struct hci_cp_write_local_name cp;
570
571 memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
572 hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp);
573 }
574
Johan Hedberg54d04db2012-02-22 15:47:48 +0200575 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
576 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
577 u8 mode = 0x01;
578 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
579 sizeof(mode), &mode);
580 } else {
581 struct hci_cp_write_eir cp;
582
583 memset(hdev->eir, 0, sizeof(hdev->eir));
584 memset(&cp, 0, sizeof(cp));
585
586 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
587 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200588 }
589
590 if (hdev->features[3] & LMP_RSSI_INQ)
591 hci_setup_inquiry_mode(hdev);
592
593 if (hdev->features[7] & LMP_INQ_TX_PWR)
594 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300595
596 if (hdev->features[7] & LMP_EXTFEATURES) {
597 struct hci_cp_read_local_ext_features cp;
598
599 cp.page = 0x01;
600 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
601 sizeof(cp), &cp);
602 }
Andre Guedese6100a22011-06-30 19:20:54 -0300603
Johan Hedberg47990ea2012-02-22 11:58:37 +0200604 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
605 u8 enable = 1;
606 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE,
607 sizeof(enable), &enable);
608 }
609
Andre Guedese6100a22011-06-30 19:20:54 -0300610 if (hdev->features[4] & LMP_LE)
611 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200612}
613
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200614static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
615{
616 struct hci_rp_read_local_version *rp = (void *) skb->data;
617
618 BT_DBG("%s status 0x%x", hdev->name, rp->status);
619
620 if (rp->status)
621 return;
622
623 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200624 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200625 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200626 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200627 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200628
629 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
630 hdev->manufacturer,
631 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200632
633 if (test_bit(HCI_INIT, &hdev->flags))
634 hci_setup(hdev);
635}
636
637static void hci_setup_link_policy(struct hci_dev *hdev)
638{
639 u16 link_policy = 0;
640
641 if (hdev->features[0] & LMP_RSWITCH)
642 link_policy |= HCI_LP_RSWITCH;
643 if (hdev->features[0] & LMP_HOLD)
644 link_policy |= HCI_LP_HOLD;
645 if (hdev->features[0] & LMP_SNIFF)
646 link_policy |= HCI_LP_SNIFF;
647 if (hdev->features[1] & LMP_PARK)
648 link_policy |= HCI_LP_PARK;
649
650 link_policy = cpu_to_le16(link_policy);
651 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
652 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200653}
654
655static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
656{
657 struct hci_rp_read_local_commands *rp = (void *) skb->data;
658
659 BT_DBG("%s status 0x%x", hdev->name, rp->status);
660
661 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200662 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200663
664 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200665
666 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
667 hci_setup_link_policy(hdev);
668
669done:
670 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200671}
672
673static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
674{
675 struct hci_rp_read_local_features *rp = (void *) skb->data;
676
677 BT_DBG("%s status 0x%x", hdev->name, rp->status);
678
679 if (rp->status)
680 return;
681
682 memcpy(hdev->features, rp->features, 8);
683
684 /* Adjust default settings according to features
685 * supported by device. */
686
687 if (hdev->features[0] & LMP_3SLOT)
688 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
689
690 if (hdev->features[0] & LMP_5SLOT)
691 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
692
693 if (hdev->features[1] & LMP_HV2) {
694 hdev->pkt_type |= (HCI_HV2);
695 hdev->esco_type |= (ESCO_HV2);
696 }
697
698 if (hdev->features[1] & LMP_HV3) {
699 hdev->pkt_type |= (HCI_HV3);
700 hdev->esco_type |= (ESCO_HV3);
701 }
702
703 if (hdev->features[3] & LMP_ESCO)
704 hdev->esco_type |= (ESCO_EV3);
705
706 if (hdev->features[4] & LMP_EV4)
707 hdev->esco_type |= (ESCO_EV4);
708
709 if (hdev->features[4] & LMP_EV5)
710 hdev->esco_type |= (ESCO_EV5);
711
Marcel Holtmannefc76882009-02-06 09:13:37 +0100712 if (hdev->features[5] & LMP_EDR_ESCO_2M)
713 hdev->esco_type |= (ESCO_2EV3);
714
715 if (hdev->features[5] & LMP_EDR_ESCO_3M)
716 hdev->esco_type |= (ESCO_3EV3);
717
718 if (hdev->features[5] & LMP_EDR_3S_ESCO)
719 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
720
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200721 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
722 hdev->features[0], hdev->features[1],
723 hdev->features[2], hdev->features[3],
724 hdev->features[4], hdev->features[5],
725 hdev->features[6], hdev->features[7]);
726}
727
Andre Guedes971e3a42011-06-30 19:20:52 -0300728static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
729 struct sk_buff *skb)
730{
731 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
732
733 BT_DBG("%s status 0x%x", hdev->name, rp->status);
734
735 if (rp->status)
736 return;
737
Andre Guedesb5b32b62011-12-30 10:34:04 -0300738 switch (rp->page) {
739 case 0:
740 memcpy(hdev->features, rp->features, 8);
741 break;
742 case 1:
743 memcpy(hdev->host_features, rp->features, 8);
744 break;
745 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300746
747 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
748}
749
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200750static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
751 struct sk_buff *skb)
752{
753 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
754
755 BT_DBG("%s status 0x%x", hdev->name, rp->status);
756
757 if (rp->status)
758 return;
759
760 hdev->flow_ctl_mode = rp->mode;
761
762 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
763}
764
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200765static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
766{
767 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
768
769 BT_DBG("%s status 0x%x", hdev->name, rp->status);
770
771 if (rp->status)
772 return;
773
774 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
775 hdev->sco_mtu = rp->sco_mtu;
776 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
777 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
778
779 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
780 hdev->sco_mtu = 64;
781 hdev->sco_pkts = 8;
782 }
783
784 hdev->acl_cnt = hdev->acl_pkts;
785 hdev->sco_cnt = hdev->sco_pkts;
786
787 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
788 hdev->acl_mtu, hdev->acl_pkts,
789 hdev->sco_mtu, hdev->sco_pkts);
790}
791
792static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
793{
794 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
795
796 BT_DBG("%s status 0x%x", hdev->name, rp->status);
797
798 if (!rp->status)
799 bacpy(&hdev->bdaddr, &rp->bdaddr);
800
Johan Hedberg23bb5762010-12-21 23:01:27 +0200801 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
802}
803
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200804static void hci_cc_read_data_block_size(struct hci_dev *hdev,
805 struct sk_buff *skb)
806{
807 struct hci_rp_read_data_block_size *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->block_mtu = __le16_to_cpu(rp->max_acl_len);
815 hdev->block_len = __le16_to_cpu(rp->block_len);
816 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
817
818 hdev->block_cnt = hdev->num_blocks;
819
820 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
821 hdev->block_cnt, hdev->block_len);
822
823 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
824}
825
Johan Hedberg23bb5762010-12-21 23:01:27 +0200826static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
827{
828 __u8 status = *((__u8 *) skb->data);
829
830 BT_DBG("%s status 0x%x", hdev->name, status);
831
832 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200833}
834
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300835static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
836 struct sk_buff *skb)
837{
838 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
839
840 BT_DBG("%s status 0x%x", hdev->name, rp->status);
841
842 if (rp->status)
843 return;
844
845 hdev->amp_status = rp->amp_status;
846 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
847 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
848 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
849 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
850 hdev->amp_type = rp->amp_type;
851 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
852 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
853 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
854 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
855
856 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
857}
858
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200859static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
860 struct sk_buff *skb)
861{
862 __u8 status = *((__u8 *) skb->data);
863
864 BT_DBG("%s status 0x%x", hdev->name, status);
865
866 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
867}
868
Johan Hedbergd5859e22011-01-25 01:19:58 +0200869static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
870{
871 __u8 status = *((__u8 *) skb->data);
872
873 BT_DBG("%s status 0x%x", hdev->name, status);
874
875 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
876}
877
878static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
879 struct sk_buff *skb)
880{
881 __u8 status = *((__u8 *) skb->data);
882
883 BT_DBG("%s status 0x%x", hdev->name, status);
884
885 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
886}
887
888static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
889 struct sk_buff *skb)
890{
891 __u8 status = *((__u8 *) skb->data);
892
893 BT_DBG("%s status 0x%x", hdev->name, status);
894
895 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
896}
897
898static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
899{
900 __u8 status = *((__u8 *) skb->data);
901
902 BT_DBG("%s status 0x%x", hdev->name, status);
903
904 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
905}
906
Johan Hedberg980e1a52011-01-22 06:10:07 +0200907static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
908{
909 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
910 struct hci_cp_pin_code_reply *cp;
911 struct hci_conn *conn;
912
913 BT_DBG("%s status 0x%x", hdev->name, rp->status);
914
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200915 hci_dev_lock(hdev);
916
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200917 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200918 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200919
920 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200921 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200922
923 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
924 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200925 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200926
927 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
928 if (conn)
929 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200930
931unlock:
932 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200933}
934
935static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
936{
937 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
938
939 BT_DBG("%s status 0x%x", hdev->name, rp->status);
940
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200941 hci_dev_lock(hdev);
942
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200943 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200944 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200945 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200946
947 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200948}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200949
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300950static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
951 struct sk_buff *skb)
952{
953 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
954
955 BT_DBG("%s status 0x%x", hdev->name, rp->status);
956
957 if (rp->status)
958 return;
959
960 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
961 hdev->le_pkts = rp->le_max_pkt;
962
963 hdev->le_cnt = hdev->le_pkts;
964
965 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
966
967 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
968}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200969
Johan Hedberga5c29682011-02-19 12:05:57 -0300970static void hci_cc_user_confirm_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
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200976 hci_dev_lock(hdev);
977
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200978 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200979 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
980 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200981
982 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300983}
984
985static void hci_cc_user_confirm_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
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200992 hci_dev_lock(hdev);
993
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200994 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200995 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200996 ACL_LINK, 0,
Johan Hedberga5c29682011-02-19 12:05:57 -0300997 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200998
999 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -03001000}
1001
Brian Gix1143d452011-11-23 08:28:34 -08001002static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
1003{
1004 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1005
1006 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1007
1008 hci_dev_lock(hdev);
1009
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001010 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001011 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1012 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001013
1014 hci_dev_unlock(hdev);
1015}
1016
1017static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1018 struct sk_buff *skb)
1019{
1020 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1021
1022 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1023
1024 hci_dev_lock(hdev);
1025
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001026 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001027 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001028 ACL_LINK, 0,
Brian Gix1143d452011-11-23 08:28:34 -08001029 rp->status);
1030
1031 hci_dev_unlock(hdev);
1032}
1033
Szymon Jancc35938b2011-03-22 13:12:21 +01001034static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1035 struct sk_buff *skb)
1036{
1037 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1038
1039 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1040
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001041 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001042 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001043 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001044 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001045}
1046
Andre Guedes07f7fa52011-12-02 21:13:31 +09001047static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1048{
1049 __u8 status = *((__u8 *) skb->data);
1050
1051 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001052
1053 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001054
1055 if (status) {
1056 hci_dev_lock(hdev);
1057 mgmt_start_discovery_failed(hdev, status);
1058 hci_dev_unlock(hdev);
1059 return;
1060 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001061}
1062
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001063static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1064 struct sk_buff *skb)
1065{
1066 struct hci_cp_le_set_scan_enable *cp;
1067 __u8 status = *((__u8 *) skb->data);
1068
1069 BT_DBG("%s status 0x%x", hdev->name, status);
1070
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001071 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1072 if (!cp)
1073 return;
1074
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001075 switch (cp->enable) {
1076 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001077 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1078
Andre Guedes3fd24152012-02-03 17:48:01 -03001079 if (status) {
1080 hci_dev_lock(hdev);
1081 mgmt_start_discovery_failed(hdev, status);
1082 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001083 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001084 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001085
Andre Guedesd23264a2011-11-25 20:53:38 -03001086 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1087
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001088 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001089
1090 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001091 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001092 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001093 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001094 break;
1095
1096 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001097 if (status)
1098 return;
1099
Andre Guedesd23264a2011-11-25 20:53:38 -03001100 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1101
Andre Guedesd0843292012-01-02 19:18:11 -03001102 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001103
1104 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1105 mgmt_interleaved_discovery(hdev);
1106 } else {
1107 hci_dev_lock(hdev);
1108 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1109 hci_dev_unlock(hdev);
1110 }
1111
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001112 break;
1113
1114 default:
1115 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1116 break;
Andre Guedes35815082011-05-26 16:23:53 -03001117 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001118}
1119
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001120static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1121{
1122 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1123
1124 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1125
1126 if (rp->status)
1127 return;
1128
1129 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1130}
1131
1132static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1133{
1134 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1135
1136 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1137
1138 if (rp->status)
1139 return;
1140
1141 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1142}
1143
Andre Guedesf9b49302011-06-30 19:20:53 -03001144static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1145 struct sk_buff *skb)
1146{
1147 struct hci_cp_read_local_ext_features cp;
Johan Hedberg06199cf2012-02-22 16:37:11 +02001148 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001149 __u8 status = *((__u8 *) skb->data);
1150
1151 BT_DBG("%s status 0x%x", hdev->name, status);
1152
Johan Hedberg06199cf2012-02-22 16:37:11 +02001153 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
1154 if (sent && test_bit(HCI_MGMT, &hdev->dev_flags))
1155 mgmt_le_enable_complete(hdev, sent->le, status);
1156
Andre Guedesf9b49302011-06-30 19:20:53 -03001157 if (status)
1158 return;
1159
1160 cp.page = 0x01;
1161 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1162}
1163
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001164static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1165{
1166 BT_DBG("%s status 0x%x", hdev->name, status);
1167
1168 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001169 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001170 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001171 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001172 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001173 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001174 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001175 return;
1176 }
1177
Andre Guedes89352e72011-11-04 14:16:53 -03001178 set_bit(HCI_INQUIRY, &hdev->flags);
1179
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001180 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001181 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001182 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001183}
1184
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1186{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001187 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001190 BT_DBG("%s status 0x%x", hdev->name, status);
1191
1192 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 if (!cp)
1194 return;
1195
1196 hci_dev_lock(hdev);
1197
1198 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1199
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001200 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201
1202 if (status) {
1203 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001204 if (status != 0x0c || conn->attempt > 2) {
1205 conn->state = BT_CLOSED;
1206 hci_proto_connect_cfm(conn, status);
1207 hci_conn_del(conn);
1208 } else
1209 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 }
1211 } else {
1212 if (!conn) {
1213 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1214 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001215 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 conn->link_mode |= HCI_LM_MASTER;
1217 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001218 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 }
1220 }
1221
1222 hci_dev_unlock(hdev);
1223}
1224
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001225static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001227 struct hci_cp_add_sco *cp;
1228 struct hci_conn *acl, *sco;
1229 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001231 BT_DBG("%s status 0x%x", hdev->name, status);
1232
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001233 if (!status)
1234 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001236 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1237 if (!cp)
1238 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001240 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001242 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001243
1244 hci_dev_lock(hdev);
1245
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001246 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001247 if (acl) {
1248 sco = acl->link;
1249 if (sco) {
1250 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001251
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001252 hci_proto_connect_cfm(sco, status);
1253 hci_conn_del(sco);
1254 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001255 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001256
1257 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258}
1259
Marcel Holtmannf8558552008-07-14 20:13:49 +02001260static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1261{
1262 struct hci_cp_auth_requested *cp;
1263 struct hci_conn *conn;
1264
1265 BT_DBG("%s status 0x%x", hdev->name, status);
1266
1267 if (!status)
1268 return;
1269
1270 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1271 if (!cp)
1272 return;
1273
1274 hci_dev_lock(hdev);
1275
1276 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1277 if (conn) {
1278 if (conn->state == BT_CONFIG) {
1279 hci_proto_connect_cfm(conn, status);
1280 hci_conn_put(conn);
1281 }
1282 }
1283
1284 hci_dev_unlock(hdev);
1285}
1286
1287static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1288{
1289 struct hci_cp_set_conn_encrypt *cp;
1290 struct hci_conn *conn;
1291
1292 BT_DBG("%s status 0x%x", hdev->name, status);
1293
1294 if (!status)
1295 return;
1296
1297 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1298 if (!cp)
1299 return;
1300
1301 hci_dev_lock(hdev);
1302
1303 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1304 if (conn) {
1305 if (conn->state == BT_CONFIG) {
1306 hci_proto_connect_cfm(conn, status);
1307 hci_conn_put(conn);
1308 }
1309 }
1310
1311 hci_dev_unlock(hdev);
1312}
1313
Johan Hedberg127178d2010-11-18 22:22:29 +02001314static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001315 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001316{
Johan Hedberg392599b2010-11-18 22:22:28 +02001317 if (conn->state != BT_CONFIG || !conn->out)
1318 return 0;
1319
Johan Hedberg765c2a92011-01-19 12:06:52 +05301320 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001321 return 0;
1322
1323 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001324 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001325 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001326 conn->pending_sec_level != BT_SECURITY_HIGH &&
1327 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001328 return 0;
1329
Johan Hedberg392599b2010-11-18 22:22:28 +02001330 return 1;
1331}
1332
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001333static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1334{
1335 struct hci_cp_remote_name_req cp;
1336
1337 memset(&cp, 0, sizeof(cp));
1338
1339 bacpy(&cp.bdaddr, &e->data.bdaddr);
1340 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1341 cp.pscan_mode = e->data.pscan_mode;
1342 cp.clock_offset = e->data.clock_offset;
1343
1344 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1345}
1346
Johan Hedbergb644ba32012-01-17 21:48:47 +02001347static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001348{
1349 struct discovery_state *discov = &hdev->discovery;
1350 struct inquiry_entry *e;
1351
Johan Hedbergb644ba32012-01-17 21:48:47 +02001352 if (list_empty(&discov->resolve))
1353 return false;
1354
1355 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1356 if (hci_resolve_name(hdev, e) == 0) {
1357 e->name_state = NAME_PENDING;
1358 return true;
1359 }
1360
1361 return false;
1362}
1363
1364static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1365 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1366{
1367 struct discovery_state *discov = &hdev->discovery;
1368 struct inquiry_entry *e;
1369
1370 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1371 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
1372 name, name_len, conn->dev_class);
1373
1374 if (discov->state == DISCOVERY_STOPPED)
1375 return;
1376
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001377 if (discov->state == DISCOVERY_STOPPING)
1378 goto discov_complete;
1379
1380 if (discov->state != DISCOVERY_RESOLVING)
1381 return;
1382
1383 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1384 if (e) {
1385 e->name_state = NAME_KNOWN;
1386 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001387 if (name)
1388 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1389 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001390 }
1391
Johan Hedbergb644ba32012-01-17 21:48:47 +02001392 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001393 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001394
1395discov_complete:
1396 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1397}
1398
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001399static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1400{
Johan Hedberg127178d2010-11-18 22:22:29 +02001401 struct hci_cp_remote_name_req *cp;
1402 struct hci_conn *conn;
1403
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001404 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001405
1406 /* If successful wait for the name req complete event before
1407 * checking for the need to do authentication */
1408 if (!status)
1409 return;
1410
1411 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1412 if (!cp)
1413 return;
1414
1415 hci_dev_lock(hdev);
1416
1417 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001418
1419 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1420 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1421
Johan Hedberg79c6c702011-04-28 11:28:55 -07001422 if (!conn)
1423 goto unlock;
1424
1425 if (!hci_outgoing_auth_needed(hdev, conn))
1426 goto unlock;
1427
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001428 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001429 struct hci_cp_auth_requested cp;
1430 cp.handle = __cpu_to_le16(conn->handle);
1431 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1432 }
1433
Johan Hedberg79c6c702011-04-28 11:28:55 -07001434unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001435 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001436}
1437
Marcel Holtmann769be972008-07-14 20:13:49 +02001438static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1439{
1440 struct hci_cp_read_remote_features *cp;
1441 struct hci_conn *conn;
1442
1443 BT_DBG("%s status 0x%x", hdev->name, status);
1444
1445 if (!status)
1446 return;
1447
1448 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1449 if (!cp)
1450 return;
1451
1452 hci_dev_lock(hdev);
1453
1454 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1455 if (conn) {
1456 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001457 hci_proto_connect_cfm(conn, status);
1458 hci_conn_put(conn);
1459 }
1460 }
1461
1462 hci_dev_unlock(hdev);
1463}
1464
1465static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1466{
1467 struct hci_cp_read_remote_ext_features *cp;
1468 struct hci_conn *conn;
1469
1470 BT_DBG("%s status 0x%x", hdev->name, status);
1471
1472 if (!status)
1473 return;
1474
1475 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1476 if (!cp)
1477 return;
1478
1479 hci_dev_lock(hdev);
1480
1481 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1482 if (conn) {
1483 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001484 hci_proto_connect_cfm(conn, status);
1485 hci_conn_put(conn);
1486 }
1487 }
1488
1489 hci_dev_unlock(hdev);
1490}
1491
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001492static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1493{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001494 struct hci_cp_setup_sync_conn *cp;
1495 struct hci_conn *acl, *sco;
1496 __u16 handle;
1497
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001498 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001499
1500 if (!status)
1501 return;
1502
1503 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1504 if (!cp)
1505 return;
1506
1507 handle = __le16_to_cpu(cp->handle);
1508
1509 BT_DBG("%s handle %d", hdev->name, handle);
1510
1511 hci_dev_lock(hdev);
1512
1513 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001514 if (acl) {
1515 sco = acl->link;
1516 if (sco) {
1517 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001518
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001519 hci_proto_connect_cfm(sco, status);
1520 hci_conn_del(sco);
1521 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001522 }
1523
1524 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001525}
1526
1527static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1528{
1529 struct hci_cp_sniff_mode *cp;
1530 struct hci_conn *conn;
1531
1532 BT_DBG("%s status 0x%x", hdev->name, status);
1533
1534 if (!status)
1535 return;
1536
1537 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1538 if (!cp)
1539 return;
1540
1541 hci_dev_lock(hdev);
1542
1543 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001544 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001545 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001546
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001547 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001548 hci_sco_setup(conn, status);
1549 }
1550
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001551 hci_dev_unlock(hdev);
1552}
1553
1554static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1555{
1556 struct hci_cp_exit_sniff_mode *cp;
1557 struct hci_conn *conn;
1558
1559 BT_DBG("%s status 0x%x", hdev->name, status);
1560
1561 if (!status)
1562 return;
1563
1564 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1565 if (!cp)
1566 return;
1567
1568 hci_dev_lock(hdev);
1569
1570 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001571 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001572 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001573
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001574 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001575 hci_sco_setup(conn, status);
1576 }
1577
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001578 hci_dev_unlock(hdev);
1579}
1580
Johan Hedberg88c3df12012-02-09 14:27:38 +02001581static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1582{
1583 struct hci_cp_disconnect *cp;
1584 struct hci_conn *conn;
1585
1586 if (!status)
1587 return;
1588
1589 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1590 if (!cp)
1591 return;
1592
1593 hci_dev_lock(hdev);
1594
1595 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1596 if (conn)
1597 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1598 conn->dst_type, status);
1599
1600 hci_dev_unlock(hdev);
1601}
1602
Ville Tervofcd89c02011-02-10 22:38:47 -03001603static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1604{
1605 struct hci_cp_le_create_conn *cp;
1606 struct hci_conn *conn;
1607
1608 BT_DBG("%s status 0x%x", hdev->name, status);
1609
1610 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1611 if (!cp)
1612 return;
1613
1614 hci_dev_lock(hdev);
1615
1616 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1617
1618 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1619 conn);
1620
1621 if (status) {
1622 if (conn && conn->state == BT_CONNECT) {
1623 conn->state = BT_CLOSED;
1624 hci_proto_connect_cfm(conn, status);
1625 hci_conn_del(conn);
1626 }
1627 } else {
1628 if (!conn) {
1629 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001630 if (conn) {
1631 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001632 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001633 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001634 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001635 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001636 }
1637 }
1638
1639 hci_dev_unlock(hdev);
1640}
1641
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001642static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1643{
1644 BT_DBG("%s status 0x%x", hdev->name, status);
1645}
1646
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001647static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1648{
1649 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001650 struct discovery_state *discov = &hdev->discovery;
1651 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001652
1653 BT_DBG("%s status %d", hdev->name, status);
1654
Johan Hedberg23bb5762010-12-21 23:01:27 +02001655 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001656
1657 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001658
1659 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1660 return;
1661
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001662 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001663 return;
1664
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001665 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001666
Andre Guedes343f9352012-02-17 20:39:37 -03001667 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001668 goto unlock;
1669
1670 if (list_empty(&discov->resolve)) {
1671 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1672 goto unlock;
1673 }
1674
1675 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1676 if (e && hci_resolve_name(hdev, e) == 0) {
1677 e->name_state = NAME_PENDING;
1678 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1679 } else {
1680 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1681 }
1682
1683unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001684 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001685}
1686
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1688{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001689 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001690 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691 int num_rsp = *((__u8 *) skb->data);
1692
1693 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1694
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001695 if (!num_rsp)
1696 return;
1697
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001699
Johan Hedberge17acd42011-03-30 23:57:16 +03001700 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001701 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001702
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 bacpy(&data.bdaddr, &info->bdaddr);
1704 data.pscan_rep_mode = info->pscan_rep_mode;
1705 data.pscan_period_mode = info->pscan_period_mode;
1706 data.pscan_mode = info->pscan_mode;
1707 memcpy(data.dev_class, info->dev_class, 3);
1708 data.clock_offset = info->clock_offset;
1709 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001710 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001711
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001712 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001713 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001714 info->dev_class, 0, !name_known, ssp,
Andre Guedes7d262f82012-01-10 18:20:49 -03001715 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001717
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 hci_dev_unlock(hdev);
1719}
1720
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001721static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001723 struct hci_ev_conn_complete *ev = (void *) skb->data;
1724 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001726 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001727
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001729
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001730 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001731 if (!conn) {
1732 if (ev->link_type != SCO_LINK)
1733 goto unlock;
1734
1735 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1736 if (!conn)
1737 goto unlock;
1738
1739 conn->type = SCO_LINK;
1740 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001741
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001742 if (!ev->status) {
1743 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001744
1745 if (conn->type == ACL_LINK) {
1746 conn->state = BT_CONFIG;
1747 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001748 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001749 } else
1750 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001751
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001752 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001753 hci_conn_add_sysfs(conn);
1754
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001755 if (test_bit(HCI_AUTH, &hdev->flags))
1756 conn->link_mode |= HCI_LM_AUTH;
1757
1758 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1759 conn->link_mode |= HCI_LM_ENCRYPT;
1760
1761 /* Get remote features */
1762 if (conn->type == ACL_LINK) {
1763 struct hci_cp_read_remote_features cp;
1764 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001765 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1766 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001767 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001768
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001769 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001770 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001771 struct hci_cp_change_conn_ptype cp;
1772 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001773 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1774 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1775 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001776 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001777 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001778 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001779 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001780 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001781 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001782 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001783
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001784 if (conn->type == ACL_LINK)
1785 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001786
Marcel Holtmann769be972008-07-14 20:13:49 +02001787 if (ev->status) {
1788 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001789 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001790 } else if (ev->link_type != ACL_LINK)
1791 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001792
1793unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001795
1796 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797}
1798
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1800{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001801 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 int mask = hdev->link_mode;
1803
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001804 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1805 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806
1807 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1808
Szymon Janc138d22e2011-02-17 16:44:23 +01001809 if ((mask & HCI_LM_ACCEPT) &&
1810 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001812 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814
1815 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001816
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001817 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1818 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001819 memcpy(ie->data.dev_class, ev->dev_class, 3);
1820
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1822 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001823 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1824 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001825 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 hci_dev_unlock(hdev);
1827 return;
1828 }
1829 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001830
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 memcpy(conn->dev_class, ev->dev_class, 3);
1832 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001833
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 hci_dev_unlock(hdev);
1835
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001836 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1837 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001839 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001841 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1842 cp.role = 0x00; /* Become master */
1843 else
1844 cp.role = 0x01; /* Remain slave */
1845
1846 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1847 sizeof(cp), &cp);
1848 } else {
1849 struct hci_cp_accept_sync_conn_req cp;
1850
1851 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001852 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001853
1854 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1855 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1856 cp.max_latency = cpu_to_le16(0xffff);
1857 cp.content_format = cpu_to_le16(hdev->voice_setting);
1858 cp.retrans_effort = 0xff;
1859
1860 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1861 sizeof(cp), &cp);
1862 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 } else {
1864 /* Connection rejected */
1865 struct hci_cp_reject_conn_req cp;
1866
1867 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001868 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001869 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 }
1871}
1872
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1874{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001875 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001876 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877
1878 BT_DBG("%s status %d", hdev->name, ev->status);
1879
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 hci_dev_lock(hdev);
1881
Marcel Holtmann04837f62006-07-03 10:02:33 +02001882 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001883 if (!conn)
1884 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001885
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001886 if (ev->status == 0)
1887 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888
Johan Hedbergb644ba32012-01-17 21:48:47 +02001889 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1890 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001891 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001892 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1893 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001894 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001895 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001896 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001897 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001898
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001899 if (ev->status == 0) {
1900 hci_proto_disconn_cfm(conn, ev->reason);
1901 hci_conn_del(conn);
1902 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001903
1904unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905 hci_dev_unlock(hdev);
1906}
1907
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001908static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1909{
1910 struct hci_ev_auth_complete *ev = (void *) skb->data;
1911 struct hci_conn *conn;
1912
1913 BT_DBG("%s status %d", hdev->name, ev->status);
1914
1915 hci_dev_lock(hdev);
1916
1917 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001918 if (!conn)
1919 goto unlock;
1920
1921 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001922 if (!hci_conn_ssp_enabled(conn) &&
1923 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001924 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001925 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001926 conn->link_mode |= HCI_LM_AUTH;
1927 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001928 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001929 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001930 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
1931 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001932 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001933
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001934 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1935 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001936
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001937 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001938 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001939 struct hci_cp_set_conn_encrypt cp;
1940 cp.handle = ev->handle;
1941 cp.encrypt = 0x01;
1942 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1943 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001944 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001945 conn->state = BT_CONNECTED;
1946 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001947 hci_conn_put(conn);
1948 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001949 } else {
1950 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001951
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001952 hci_conn_hold(conn);
1953 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1954 hci_conn_put(conn);
1955 }
1956
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001957 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001958 if (!ev->status) {
1959 struct hci_cp_set_conn_encrypt cp;
1960 cp.handle = ev->handle;
1961 cp.encrypt = 0x01;
1962 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1963 &cp);
1964 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001965 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001966 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001967 }
1968 }
1969
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001970unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001971 hci_dev_unlock(hdev);
1972}
1973
1974static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1975{
Johan Hedberg127178d2010-11-18 22:22:29 +02001976 struct hci_ev_remote_name *ev = (void *) skb->data;
1977 struct hci_conn *conn;
1978
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001979 BT_DBG("%s", hdev->name);
1980
1981 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001982
1983 hci_dev_lock(hdev);
1984
1985 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001986
1987 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1988 goto check_auth;
1989
1990 if (ev->status == 0)
1991 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1992 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1993 else
1994 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1995
1996check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001997 if (!conn)
1998 goto unlock;
1999
2000 if (!hci_outgoing_auth_needed(hdev, conn))
2001 goto unlock;
2002
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002003 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002004 struct hci_cp_auth_requested cp;
2005 cp.handle = __cpu_to_le16(conn->handle);
2006 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2007 }
2008
Johan Hedberg79c6c702011-04-28 11:28:55 -07002009unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002010 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002011}
2012
2013static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2014{
2015 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2016 struct hci_conn *conn;
2017
2018 BT_DBG("%s status %d", hdev->name, ev->status);
2019
2020 hci_dev_lock(hdev);
2021
2022 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2023 if (conn) {
2024 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002025 if (ev->encrypt) {
2026 /* Encryption implies authentication */
2027 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002028 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002029 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002030 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002031 conn->link_mode &= ~HCI_LM_ENCRYPT;
2032 }
2033
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002034 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002035
Marcel Holtmannf8558552008-07-14 20:13:49 +02002036 if (conn->state == BT_CONFIG) {
2037 if (!ev->status)
2038 conn->state = BT_CONNECTED;
2039
2040 hci_proto_connect_cfm(conn, ev->status);
2041 hci_conn_put(conn);
2042 } else
2043 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002044 }
2045
2046 hci_dev_unlock(hdev);
2047}
2048
2049static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2050{
2051 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2052 struct hci_conn *conn;
2053
2054 BT_DBG("%s status %d", hdev->name, ev->status);
2055
2056 hci_dev_lock(hdev);
2057
2058 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2059 if (conn) {
2060 if (!ev->status)
2061 conn->link_mode |= HCI_LM_SECURE;
2062
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002063 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002064
2065 hci_key_change_cfm(conn, ev->status);
2066 }
2067
2068 hci_dev_unlock(hdev);
2069}
2070
2071static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2072{
2073 struct hci_ev_remote_features *ev = (void *) skb->data;
2074 struct hci_conn *conn;
2075
2076 BT_DBG("%s status %d", hdev->name, ev->status);
2077
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002078 hci_dev_lock(hdev);
2079
2080 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002081 if (!conn)
2082 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002083
Johan Hedbergccd556f2010-11-10 17:11:51 +02002084 if (!ev->status)
2085 memcpy(conn->features, ev->features, 8);
2086
2087 if (conn->state != BT_CONFIG)
2088 goto unlock;
2089
2090 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2091 struct hci_cp_read_remote_ext_features cp;
2092 cp.handle = ev->handle;
2093 cp.page = 0x01;
2094 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002095 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002096 goto unlock;
2097 }
2098
Johan Hedberg127178d2010-11-18 22:22:29 +02002099 if (!ev->status) {
2100 struct hci_cp_remote_name_req cp;
2101 memset(&cp, 0, sizeof(cp));
2102 bacpy(&cp.bdaddr, &conn->dst);
2103 cp.pscan_rep_mode = 0x02;
2104 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002105 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2106 mgmt_device_connected(hdev, &conn->dst, conn->type,
2107 conn->dst_type, NULL, 0,
2108 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002109
Johan Hedberg127178d2010-11-18 22:22:29 +02002110 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002111 conn->state = BT_CONNECTED;
2112 hci_proto_connect_cfm(conn, ev->status);
2113 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002114 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002115
Johan Hedbergccd556f2010-11-10 17:11:51 +02002116unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002117 hci_dev_unlock(hdev);
2118}
2119
2120static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2121{
2122 BT_DBG("%s", hdev->name);
2123}
2124
2125static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2126{
2127 BT_DBG("%s", hdev->name);
2128}
2129
2130static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2131{
2132 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2133 __u16 opcode;
2134
2135 skb_pull(skb, sizeof(*ev));
2136
2137 opcode = __le16_to_cpu(ev->opcode);
2138
2139 switch (opcode) {
2140 case HCI_OP_INQUIRY_CANCEL:
2141 hci_cc_inquiry_cancel(hdev, skb);
2142 break;
2143
2144 case HCI_OP_EXIT_PERIODIC_INQ:
2145 hci_cc_exit_periodic_inq(hdev, skb);
2146 break;
2147
2148 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2149 hci_cc_remote_name_req_cancel(hdev, skb);
2150 break;
2151
2152 case HCI_OP_ROLE_DISCOVERY:
2153 hci_cc_role_discovery(hdev, skb);
2154 break;
2155
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002156 case HCI_OP_READ_LINK_POLICY:
2157 hci_cc_read_link_policy(hdev, skb);
2158 break;
2159
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002160 case HCI_OP_WRITE_LINK_POLICY:
2161 hci_cc_write_link_policy(hdev, skb);
2162 break;
2163
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002164 case HCI_OP_READ_DEF_LINK_POLICY:
2165 hci_cc_read_def_link_policy(hdev, skb);
2166 break;
2167
2168 case HCI_OP_WRITE_DEF_LINK_POLICY:
2169 hci_cc_write_def_link_policy(hdev, skb);
2170 break;
2171
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002172 case HCI_OP_RESET:
2173 hci_cc_reset(hdev, skb);
2174 break;
2175
2176 case HCI_OP_WRITE_LOCAL_NAME:
2177 hci_cc_write_local_name(hdev, skb);
2178 break;
2179
2180 case HCI_OP_READ_LOCAL_NAME:
2181 hci_cc_read_local_name(hdev, skb);
2182 break;
2183
2184 case HCI_OP_WRITE_AUTH_ENABLE:
2185 hci_cc_write_auth_enable(hdev, skb);
2186 break;
2187
2188 case HCI_OP_WRITE_ENCRYPT_MODE:
2189 hci_cc_write_encrypt_mode(hdev, skb);
2190 break;
2191
2192 case HCI_OP_WRITE_SCAN_ENABLE:
2193 hci_cc_write_scan_enable(hdev, skb);
2194 break;
2195
2196 case HCI_OP_READ_CLASS_OF_DEV:
2197 hci_cc_read_class_of_dev(hdev, skb);
2198 break;
2199
2200 case HCI_OP_WRITE_CLASS_OF_DEV:
2201 hci_cc_write_class_of_dev(hdev, skb);
2202 break;
2203
2204 case HCI_OP_READ_VOICE_SETTING:
2205 hci_cc_read_voice_setting(hdev, skb);
2206 break;
2207
2208 case HCI_OP_WRITE_VOICE_SETTING:
2209 hci_cc_write_voice_setting(hdev, skb);
2210 break;
2211
2212 case HCI_OP_HOST_BUFFER_SIZE:
2213 hci_cc_host_buffer_size(hdev, skb);
2214 break;
2215
Marcel Holtmann333140b2008-07-14 20:13:48 +02002216 case HCI_OP_WRITE_SSP_MODE:
2217 hci_cc_write_ssp_mode(hdev, skb);
2218 break;
2219
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002220 case HCI_OP_READ_LOCAL_VERSION:
2221 hci_cc_read_local_version(hdev, skb);
2222 break;
2223
2224 case HCI_OP_READ_LOCAL_COMMANDS:
2225 hci_cc_read_local_commands(hdev, skb);
2226 break;
2227
2228 case HCI_OP_READ_LOCAL_FEATURES:
2229 hci_cc_read_local_features(hdev, skb);
2230 break;
2231
Andre Guedes971e3a42011-06-30 19:20:52 -03002232 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2233 hci_cc_read_local_ext_features(hdev, skb);
2234 break;
2235
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002236 case HCI_OP_READ_BUFFER_SIZE:
2237 hci_cc_read_buffer_size(hdev, skb);
2238 break;
2239
2240 case HCI_OP_READ_BD_ADDR:
2241 hci_cc_read_bd_addr(hdev, skb);
2242 break;
2243
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002244 case HCI_OP_READ_DATA_BLOCK_SIZE:
2245 hci_cc_read_data_block_size(hdev, skb);
2246 break;
2247
Johan Hedberg23bb5762010-12-21 23:01:27 +02002248 case HCI_OP_WRITE_CA_TIMEOUT:
2249 hci_cc_write_ca_timeout(hdev, skb);
2250 break;
2251
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002252 case HCI_OP_READ_FLOW_CONTROL_MODE:
2253 hci_cc_read_flow_control_mode(hdev, skb);
2254 break;
2255
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002256 case HCI_OP_READ_LOCAL_AMP_INFO:
2257 hci_cc_read_local_amp_info(hdev, skb);
2258 break;
2259
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002260 case HCI_OP_DELETE_STORED_LINK_KEY:
2261 hci_cc_delete_stored_link_key(hdev, skb);
2262 break;
2263
Johan Hedbergd5859e22011-01-25 01:19:58 +02002264 case HCI_OP_SET_EVENT_MASK:
2265 hci_cc_set_event_mask(hdev, skb);
2266 break;
2267
2268 case HCI_OP_WRITE_INQUIRY_MODE:
2269 hci_cc_write_inquiry_mode(hdev, skb);
2270 break;
2271
2272 case HCI_OP_READ_INQ_RSP_TX_POWER:
2273 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2274 break;
2275
2276 case HCI_OP_SET_EVENT_FLT:
2277 hci_cc_set_event_flt(hdev, skb);
2278 break;
2279
Johan Hedberg980e1a52011-01-22 06:10:07 +02002280 case HCI_OP_PIN_CODE_REPLY:
2281 hci_cc_pin_code_reply(hdev, skb);
2282 break;
2283
2284 case HCI_OP_PIN_CODE_NEG_REPLY:
2285 hci_cc_pin_code_neg_reply(hdev, skb);
2286 break;
2287
Szymon Jancc35938b2011-03-22 13:12:21 +01002288 case HCI_OP_READ_LOCAL_OOB_DATA:
2289 hci_cc_read_local_oob_data_reply(hdev, skb);
2290 break;
2291
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002292 case HCI_OP_LE_READ_BUFFER_SIZE:
2293 hci_cc_le_read_buffer_size(hdev, skb);
2294 break;
2295
Johan Hedberga5c29682011-02-19 12:05:57 -03002296 case HCI_OP_USER_CONFIRM_REPLY:
2297 hci_cc_user_confirm_reply(hdev, skb);
2298 break;
2299
2300 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2301 hci_cc_user_confirm_neg_reply(hdev, skb);
2302 break;
2303
Brian Gix1143d452011-11-23 08:28:34 -08002304 case HCI_OP_USER_PASSKEY_REPLY:
2305 hci_cc_user_passkey_reply(hdev, skb);
2306 break;
2307
2308 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2309 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002310
2311 case HCI_OP_LE_SET_SCAN_PARAM:
2312 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002313 break;
2314
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002315 case HCI_OP_LE_SET_SCAN_ENABLE:
2316 hci_cc_le_set_scan_enable(hdev, skb);
2317 break;
2318
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002319 case HCI_OP_LE_LTK_REPLY:
2320 hci_cc_le_ltk_reply(hdev, skb);
2321 break;
2322
2323 case HCI_OP_LE_LTK_NEG_REPLY:
2324 hci_cc_le_ltk_neg_reply(hdev, skb);
2325 break;
2326
Andre Guedesf9b49302011-06-30 19:20:53 -03002327 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2328 hci_cc_write_le_host_supported(hdev, skb);
2329 break;
2330
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002331 default:
2332 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2333 break;
2334 }
2335
Ville Tervo6bd32322011-02-16 16:32:41 +02002336 if (ev->opcode != HCI_OP_NOP)
2337 del_timer(&hdev->cmd_timer);
2338
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002339 if (ev->ncmd) {
2340 atomic_set(&hdev->cmd_cnt, 1);
2341 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002342 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002343 }
2344}
2345
2346static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2347{
2348 struct hci_ev_cmd_status *ev = (void *) skb->data;
2349 __u16 opcode;
2350
2351 skb_pull(skb, sizeof(*ev));
2352
2353 opcode = __le16_to_cpu(ev->opcode);
2354
2355 switch (opcode) {
2356 case HCI_OP_INQUIRY:
2357 hci_cs_inquiry(hdev, ev->status);
2358 break;
2359
2360 case HCI_OP_CREATE_CONN:
2361 hci_cs_create_conn(hdev, ev->status);
2362 break;
2363
2364 case HCI_OP_ADD_SCO:
2365 hci_cs_add_sco(hdev, ev->status);
2366 break;
2367
Marcel Holtmannf8558552008-07-14 20:13:49 +02002368 case HCI_OP_AUTH_REQUESTED:
2369 hci_cs_auth_requested(hdev, ev->status);
2370 break;
2371
2372 case HCI_OP_SET_CONN_ENCRYPT:
2373 hci_cs_set_conn_encrypt(hdev, ev->status);
2374 break;
2375
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002376 case HCI_OP_REMOTE_NAME_REQ:
2377 hci_cs_remote_name_req(hdev, ev->status);
2378 break;
2379
Marcel Holtmann769be972008-07-14 20:13:49 +02002380 case HCI_OP_READ_REMOTE_FEATURES:
2381 hci_cs_read_remote_features(hdev, ev->status);
2382 break;
2383
2384 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2385 hci_cs_read_remote_ext_features(hdev, ev->status);
2386 break;
2387
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002388 case HCI_OP_SETUP_SYNC_CONN:
2389 hci_cs_setup_sync_conn(hdev, ev->status);
2390 break;
2391
2392 case HCI_OP_SNIFF_MODE:
2393 hci_cs_sniff_mode(hdev, ev->status);
2394 break;
2395
2396 case HCI_OP_EXIT_SNIFF_MODE:
2397 hci_cs_exit_sniff_mode(hdev, ev->status);
2398 break;
2399
Johan Hedberg8962ee72011-01-20 12:40:27 +02002400 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002401 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002402 break;
2403
Ville Tervofcd89c02011-02-10 22:38:47 -03002404 case HCI_OP_LE_CREATE_CONN:
2405 hci_cs_le_create_conn(hdev, ev->status);
2406 break;
2407
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002408 case HCI_OP_LE_START_ENC:
2409 hci_cs_le_start_enc(hdev, ev->status);
2410 break;
2411
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002412 default:
2413 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2414 break;
2415 }
2416
Ville Tervo6bd32322011-02-16 16:32:41 +02002417 if (ev->opcode != HCI_OP_NOP)
2418 del_timer(&hdev->cmd_timer);
2419
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002420 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002421 atomic_set(&hdev->cmd_cnt, 1);
2422 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002423 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002424 }
2425}
2426
2427static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2428{
2429 struct hci_ev_role_change *ev = (void *) skb->data;
2430 struct hci_conn *conn;
2431
2432 BT_DBG("%s status %d", hdev->name, ev->status);
2433
2434 hci_dev_lock(hdev);
2435
2436 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2437 if (conn) {
2438 if (!ev->status) {
2439 if (ev->role)
2440 conn->link_mode &= ~HCI_LM_MASTER;
2441 else
2442 conn->link_mode |= HCI_LM_MASTER;
2443 }
2444
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002445 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002446
2447 hci_role_switch_cfm(conn, ev->status, ev->role);
2448 }
2449
2450 hci_dev_unlock(hdev);
2451}
2452
Linus Torvalds1da177e2005-04-16 15:20:36 -07002453static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2454{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002455 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456 int i;
2457
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002458 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2459 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2460 return;
2461 }
2462
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002463 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2464 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002465 BT_DBG("%s bad parameters", hdev->name);
2466 return;
2467 }
2468
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002469 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2470
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002471 for (i = 0; i < ev->num_hndl; i++) {
2472 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473 struct hci_conn *conn;
2474 __u16 handle, count;
2475
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002476 handle = __le16_to_cpu(info->handle);
2477 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002478
2479 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002480 if (!conn)
2481 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002483 conn->sent -= count;
2484
2485 switch (conn->type) {
2486 case ACL_LINK:
2487 hdev->acl_cnt += count;
2488 if (hdev->acl_cnt > hdev->acl_pkts)
2489 hdev->acl_cnt = hdev->acl_pkts;
2490 break;
2491
2492 case LE_LINK:
2493 if (hdev->le_pkts) {
2494 hdev->le_cnt += count;
2495 if (hdev->le_cnt > hdev->le_pkts)
2496 hdev->le_cnt = hdev->le_pkts;
2497 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002498 hdev->acl_cnt += count;
2499 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500 hdev->acl_cnt = hdev->acl_pkts;
2501 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002502 break;
2503
2504 case SCO_LINK:
2505 hdev->sco_cnt += count;
2506 if (hdev->sco_cnt > hdev->sco_pkts)
2507 hdev->sco_cnt = hdev->sco_pkts;
2508 break;
2509
2510 default:
2511 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2512 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002513 }
2514 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002515
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002516 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002517}
2518
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002519static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2520 struct sk_buff *skb)
2521{
2522 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2523 int i;
2524
2525 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2526 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2527 return;
2528 }
2529
2530 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2531 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2532 BT_DBG("%s bad parameters", hdev->name);
2533 return;
2534 }
2535
2536 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2537 ev->num_hndl);
2538
2539 for (i = 0; i < ev->num_hndl; i++) {
2540 struct hci_comp_blocks_info *info = &ev->handles[i];
2541 struct hci_conn *conn;
2542 __u16 handle, block_count;
2543
2544 handle = __le16_to_cpu(info->handle);
2545 block_count = __le16_to_cpu(info->blocks);
2546
2547 conn = hci_conn_hash_lookup_handle(hdev, handle);
2548 if (!conn)
2549 continue;
2550
2551 conn->sent -= block_count;
2552
2553 switch (conn->type) {
2554 case ACL_LINK:
2555 hdev->block_cnt += block_count;
2556 if (hdev->block_cnt > hdev->num_blocks)
2557 hdev->block_cnt = hdev->num_blocks;
2558 break;
2559
2560 default:
2561 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2562 break;
2563 }
2564 }
2565
2566 queue_work(hdev->workqueue, &hdev->tx_work);
2567}
2568
Marcel Holtmann04837f62006-07-03 10:02:33 +02002569static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002571 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002572 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002573
2574 BT_DBG("%s status %d", hdev->name, ev->status);
2575
2576 hci_dev_lock(hdev);
2577
Marcel Holtmann04837f62006-07-03 10:02:33 +02002578 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2579 if (conn) {
2580 conn->mode = ev->mode;
2581 conn->interval = __le16_to_cpu(ev->interval);
2582
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002583 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002584 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002585 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002586 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002587 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002588 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002589
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002590 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002591 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002592 }
2593
2594 hci_dev_unlock(hdev);
2595}
2596
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2598{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002599 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2600 struct hci_conn *conn;
2601
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002602 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002603
2604 hci_dev_lock(hdev);
2605
2606 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002607 if (!conn)
2608 goto unlock;
2609
2610 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002611 hci_conn_hold(conn);
2612 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2613 hci_conn_put(conn);
2614 }
2615
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002616 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002617 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2618 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002619 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002620 u8 secure;
2621
2622 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2623 secure = 1;
2624 else
2625 secure = 0;
2626
Johan Hedberg744cf192011-11-08 20:40:14 +02002627 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002628 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002629
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002630unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002631 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632}
2633
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2635{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002636 struct hci_ev_link_key_req *ev = (void *) skb->data;
2637 struct hci_cp_link_key_reply cp;
2638 struct hci_conn *conn;
2639 struct link_key *key;
2640
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002641 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002642
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002643 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002644 return;
2645
2646 hci_dev_lock(hdev);
2647
2648 key = hci_find_link_key(hdev, &ev->bdaddr);
2649 if (!key) {
2650 BT_DBG("%s link key not found for %s", hdev->name,
2651 batostr(&ev->bdaddr));
2652 goto not_found;
2653 }
2654
2655 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2656 batostr(&ev->bdaddr));
2657
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002658 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002659 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002660 BT_DBG("%s ignoring debug key", hdev->name);
2661 goto not_found;
2662 }
2663
2664 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002665 if (conn) {
2666 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2667 conn->auth_type != 0xff &&
2668 (conn->auth_type & 0x01)) {
2669 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2670 goto not_found;
2671 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002672
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002673 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2674 conn->pending_sec_level == BT_SECURITY_HIGH) {
2675 BT_DBG("%s ignoring key unauthenticated for high \
2676 security", hdev->name);
2677 goto not_found;
2678 }
2679
2680 conn->key_type = key->type;
2681 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002682 }
2683
2684 bacpy(&cp.bdaddr, &ev->bdaddr);
2685 memcpy(cp.link_key, key->val, 16);
2686
2687 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2688
2689 hci_dev_unlock(hdev);
2690
2691 return;
2692
2693not_found:
2694 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2695 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696}
2697
Linus Torvalds1da177e2005-04-16 15:20:36 -07002698static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2699{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002700 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2701 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002702 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002703
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002704 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002705
2706 hci_dev_lock(hdev);
2707
2708 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2709 if (conn) {
2710 hci_conn_hold(conn);
2711 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002712 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002713
2714 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2715 conn->key_type = ev->key_type;
2716
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002717 hci_conn_put(conn);
2718 }
2719
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002720 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002721 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002722 ev->key_type, pin_len);
2723
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002724 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725}
2726
Marcel Holtmann04837f62006-07-03 10:02:33 +02002727static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2728{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002729 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002730 struct hci_conn *conn;
2731
2732 BT_DBG("%s status %d", hdev->name, ev->status);
2733
2734 hci_dev_lock(hdev);
2735
2736 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002737 if (conn && !ev->status) {
2738 struct inquiry_entry *ie;
2739
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002740 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2741 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742 ie->data.clock_offset = ev->clock_offset;
2743 ie->timestamp = jiffies;
2744 }
2745 }
2746
2747 hci_dev_unlock(hdev);
2748}
2749
Marcel Holtmanna8746412008-07-14 20:13:46 +02002750static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2751{
2752 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2753 struct hci_conn *conn;
2754
2755 BT_DBG("%s status %d", hdev->name, ev->status);
2756
2757 hci_dev_lock(hdev);
2758
2759 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2760 if (conn && !ev->status)
2761 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2762
2763 hci_dev_unlock(hdev);
2764}
2765
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002766static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2767{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002768 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002769 struct inquiry_entry *ie;
2770
2771 BT_DBG("%s", hdev->name);
2772
2773 hci_dev_lock(hdev);
2774
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002775 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2776 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002777 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2778 ie->timestamp = jiffies;
2779 }
2780
2781 hci_dev_unlock(hdev);
2782}
2783
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002784static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2785{
2786 struct inquiry_data data;
2787 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002788 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002789
2790 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2791
2792 if (!num_rsp)
2793 return;
2794
2795 hci_dev_lock(hdev);
2796
2797 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002798 struct inquiry_info_with_rssi_and_pscan_mode *info;
2799 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002800
Johan Hedberge17acd42011-03-30 23:57:16 +03002801 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002802 bacpy(&data.bdaddr, &info->bdaddr);
2803 data.pscan_rep_mode = info->pscan_rep_mode;
2804 data.pscan_period_mode = info->pscan_period_mode;
2805 data.pscan_mode = info->pscan_mode;
2806 memcpy(data.dev_class, info->dev_class, 3);
2807 data.clock_offset = info->clock_offset;
2808 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002809 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002810
2811 name_known = hci_inquiry_cache_update(hdev, &data,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002812 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002813 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002814 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002815 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002816 }
2817 } else {
2818 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2819
Johan Hedberge17acd42011-03-30 23:57:16 +03002820 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002821 bacpy(&data.bdaddr, &info->bdaddr);
2822 data.pscan_rep_mode = info->pscan_rep_mode;
2823 data.pscan_period_mode = info->pscan_period_mode;
2824 data.pscan_mode = 0x00;
2825 memcpy(data.dev_class, info->dev_class, 3);
2826 data.clock_offset = info->clock_offset;
2827 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002828 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002829 name_known = hci_inquiry_cache_update(hdev, &data,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002830 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002831 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002832 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002833 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002834 }
2835 }
2836
2837 hci_dev_unlock(hdev);
2838}
2839
2840static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2841{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002842 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2843 struct hci_conn *conn;
2844
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002845 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002846
Marcel Holtmann41a96212008-07-14 20:13:48 +02002847 hci_dev_lock(hdev);
2848
2849 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002850 if (!conn)
2851 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002852
Johan Hedbergccd556f2010-11-10 17:11:51 +02002853 if (!ev->status && ev->page == 0x01) {
2854 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002855
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002856 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2857 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002858 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002859
Johan Hedberg58a681e2012-01-16 06:47:28 +02002860 if (ev->features[0] & 0x01)
2861 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002862 }
2863
Johan Hedbergccd556f2010-11-10 17:11:51 +02002864 if (conn->state != BT_CONFIG)
2865 goto unlock;
2866
Johan Hedberg127178d2010-11-18 22:22:29 +02002867 if (!ev->status) {
2868 struct hci_cp_remote_name_req cp;
2869 memset(&cp, 0, sizeof(cp));
2870 bacpy(&cp.bdaddr, &conn->dst);
2871 cp.pscan_rep_mode = 0x02;
2872 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002873 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2874 mgmt_device_connected(hdev, &conn->dst, conn->type,
2875 conn->dst_type, NULL, 0,
2876 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002877
Johan Hedberg127178d2010-11-18 22:22:29 +02002878 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002879 conn->state = BT_CONNECTED;
2880 hci_proto_connect_cfm(conn, ev->status);
2881 hci_conn_put(conn);
2882 }
2883
2884unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002885 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002886}
2887
2888static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2889{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002890 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2891 struct hci_conn *conn;
2892
2893 BT_DBG("%s status %d", hdev->name, ev->status);
2894
2895 hci_dev_lock(hdev);
2896
2897 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002898 if (!conn) {
2899 if (ev->link_type == ESCO_LINK)
2900 goto unlock;
2901
2902 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2903 if (!conn)
2904 goto unlock;
2905
2906 conn->type = SCO_LINK;
2907 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002908
Marcel Holtmann732547f2009-04-19 19:14:14 +02002909 switch (ev->status) {
2910 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002911 conn->handle = __le16_to_cpu(ev->handle);
2912 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002913
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002914 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002915 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002916 break;
2917
Stephen Coe705e5712010-02-16 11:29:44 -05002918 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002919 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002920 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002921 case 0x1f: /* Unspecified error */
2922 if (conn->out && conn->attempt < 2) {
2923 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2924 (hdev->esco_type & EDR_ESCO_MASK);
2925 hci_setup_sync(conn, conn->link->handle);
2926 goto unlock;
2927 }
2928 /* fall through */
2929
2930 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002931 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002932 break;
2933 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002934
2935 hci_proto_connect_cfm(conn, ev->status);
2936 if (ev->status)
2937 hci_conn_del(conn);
2938
2939unlock:
2940 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002941}
2942
2943static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2944{
2945 BT_DBG("%s", hdev->name);
2946}
2947
Marcel Holtmann04837f62006-07-03 10:02:33 +02002948static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2949{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002950 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002951
2952 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002953}
2954
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002955static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2956{
2957 struct inquiry_data data;
2958 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2959 int num_rsp = *((__u8 *) skb->data);
2960
2961 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2962
2963 if (!num_rsp)
2964 return;
2965
2966 hci_dev_lock(hdev);
2967
Johan Hedberge17acd42011-03-30 23:57:16 +03002968 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002969 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002970
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002971 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002972 data.pscan_rep_mode = info->pscan_rep_mode;
2973 data.pscan_period_mode = info->pscan_period_mode;
2974 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002975 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002976 data.clock_offset = info->clock_offset;
2977 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002978 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002979
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002980 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002981 name_known = eir_has_data_type(info->data,
2982 sizeof(info->data),
2983 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002984 else
2985 name_known = true;
2986
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002987 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
2988 &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002989 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002990 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002991 !name_known, ssp, info->data,
Andre Guedes7d262f82012-01-10 18:20:49 -03002992 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002993 }
2994
2995 hci_dev_unlock(hdev);
2996}
2997
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002998static inline u8 hci_get_auth_req(struct hci_conn *conn)
2999{
3000 /* If remote requests dedicated bonding follow that lead */
3001 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3002 /* If both remote and local IO capabilities allow MITM
3003 * protection then require it, otherwise don't */
3004 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3005 return 0x02;
3006 else
3007 return 0x03;
3008 }
3009
3010 /* If remote requests no-bonding follow that lead */
3011 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003012 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003013
3014 return conn->auth_type;
3015}
3016
Marcel Holtmann04936842008-07-14 20:13:48 +02003017static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3018{
3019 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3020 struct hci_conn *conn;
3021
3022 BT_DBG("%s", hdev->name);
3023
3024 hci_dev_lock(hdev);
3025
3026 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003027 if (!conn)
3028 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003029
Johan Hedberg03b555e2011-01-04 15:40:05 +02003030 hci_conn_hold(conn);
3031
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003032 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003033 goto unlock;
3034
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003035 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003036 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003037 struct hci_cp_io_capability_reply cp;
3038
3039 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303040 /* Change the IO capability from KeyboardDisplay
3041 * to DisplayYesNo as it is not supported by BT spec. */
3042 cp.capability = (conn->io_capability == 0x04) ?
3043 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003044 conn->auth_type = hci_get_auth_req(conn);
3045 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003046
Johan Hedberg58a681e2012-01-16 06:47:28 +02003047 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003048 hci_find_remote_oob_data(hdev, &conn->dst))
3049 cp.oob_data = 0x01;
3050 else
3051 cp.oob_data = 0x00;
3052
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003053 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3054 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003055 } else {
3056 struct hci_cp_io_capability_neg_reply cp;
3057
3058 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003059 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003060
3061 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3062 sizeof(cp), &cp);
3063 }
3064
3065unlock:
3066 hci_dev_unlock(hdev);
3067}
3068
3069static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3070{
3071 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3072 struct hci_conn *conn;
3073
3074 BT_DBG("%s", hdev->name);
3075
3076 hci_dev_lock(hdev);
3077
3078 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3079 if (!conn)
3080 goto unlock;
3081
Johan Hedberg03b555e2011-01-04 15:40:05 +02003082 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003083 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003084 if (ev->oob_data)
3085 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003086
3087unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003088 hci_dev_unlock(hdev);
3089}
3090
Johan Hedberga5c29682011-02-19 12:05:57 -03003091static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3092 struct sk_buff *skb)
3093{
3094 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003095 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003096 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003097
3098 BT_DBG("%s", hdev->name);
3099
3100 hci_dev_lock(hdev);
3101
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003102 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003103 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003104
Johan Hedberg7a828902011-04-28 11:28:53 -07003105 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3106 if (!conn)
3107 goto unlock;
3108
3109 loc_mitm = (conn->auth_type & 0x01);
3110 rem_mitm = (conn->remote_auth & 0x01);
3111
3112 /* If we require MITM but the remote device can't provide that
3113 * (it has NoInputNoOutput) then reject the confirmation
3114 * request. The only exception is when we're dedicated bonding
3115 * initiators (connect_cfm_cb set) since then we always have the MITM
3116 * bit set. */
3117 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3118 BT_DBG("Rejecting request: remote device can't provide MITM");
3119 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3120 sizeof(ev->bdaddr), &ev->bdaddr);
3121 goto unlock;
3122 }
3123
3124 /* If no side requires MITM protection; auto-accept */
3125 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3126 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003127
3128 /* If we're not the initiators request authorization to
3129 * proceed from user space (mgmt_user_confirm with
3130 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003131 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003132 BT_DBG("Confirming auto-accept as acceptor");
3133 confirm_hint = 1;
3134 goto confirm;
3135 }
3136
Johan Hedberg9f616562011-04-28 11:28:54 -07003137 BT_DBG("Auto-accept of user confirmation with %ums delay",
3138 hdev->auto_accept_delay);
3139
3140 if (hdev->auto_accept_delay > 0) {
3141 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3142 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3143 goto unlock;
3144 }
3145
Johan Hedberg7a828902011-04-28 11:28:53 -07003146 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3147 sizeof(ev->bdaddr), &ev->bdaddr);
3148 goto unlock;
3149 }
3150
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003151confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003152 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003153 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003154
3155unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003156 hci_dev_unlock(hdev);
3157}
3158
Brian Gix1143d452011-11-23 08:28:34 -08003159static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3160 struct sk_buff *skb)
3161{
3162 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3163
3164 BT_DBG("%s", hdev->name);
3165
3166 hci_dev_lock(hdev);
3167
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003168 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003169 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003170
3171 hci_dev_unlock(hdev);
3172}
3173
Marcel Holtmann04936842008-07-14 20:13:48 +02003174static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3175{
3176 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3177 struct hci_conn *conn;
3178
3179 BT_DBG("%s", hdev->name);
3180
3181 hci_dev_lock(hdev);
3182
3183 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003184 if (!conn)
3185 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003186
Johan Hedberg2a611692011-02-19 12:06:00 -03003187 /* To avoid duplicate auth_failed events to user space we check
3188 * the HCI_CONN_AUTH_PEND flag which will be set if we
3189 * initiated the authentication. A traditional auth_complete
3190 * event gets always produced as initiator and is also mapped to
3191 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003192 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003193 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3194 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003195
3196 hci_conn_put(conn);
3197
3198unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003199 hci_dev_unlock(hdev);
3200}
3201
Marcel Holtmann41a96212008-07-14 20:13:48 +02003202static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3203{
3204 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3205 struct inquiry_entry *ie;
3206
3207 BT_DBG("%s", hdev->name);
3208
3209 hci_dev_lock(hdev);
3210
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003211 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3212 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003213 ie->data.ssp_mode = (ev->features[0] & 0x01);
3214
3215 hci_dev_unlock(hdev);
3216}
3217
Szymon Janc2763eda2011-03-22 13:12:22 +01003218static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3219 struct sk_buff *skb)
3220{
3221 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3222 struct oob_data *data;
3223
3224 BT_DBG("%s", hdev->name);
3225
3226 hci_dev_lock(hdev);
3227
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003228 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003229 goto unlock;
3230
Szymon Janc2763eda2011-03-22 13:12:22 +01003231 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3232 if (data) {
3233 struct hci_cp_remote_oob_data_reply cp;
3234
3235 bacpy(&cp.bdaddr, &ev->bdaddr);
3236 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3237 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3238
3239 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3240 &cp);
3241 } else {
3242 struct hci_cp_remote_oob_data_neg_reply cp;
3243
3244 bacpy(&cp.bdaddr, &ev->bdaddr);
3245 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3246 &cp);
3247 }
3248
Szymon Jance1ba1f12011-04-06 13:01:59 +02003249unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003250 hci_dev_unlock(hdev);
3251}
3252
Ville Tervofcd89c02011-02-10 22:38:47 -03003253static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3254{
3255 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3256 struct hci_conn *conn;
3257
3258 BT_DBG("%s status %d", hdev->name, ev->status);
3259
3260 hci_dev_lock(hdev);
3261
3262 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003263 if (!conn) {
3264 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3265 if (!conn) {
3266 BT_ERR("No memory for new connection");
3267 hci_dev_unlock(hdev);
3268 return;
3269 }
Andre Guedes29b79882011-05-31 14:20:54 -03003270
3271 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003272 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003273
3274 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003275 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3276 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003277 hci_proto_connect_cfm(conn, ev->status);
3278 conn->state = BT_CLOSED;
3279 hci_conn_del(conn);
3280 goto unlock;
3281 }
3282
Johan Hedbergb644ba32012-01-17 21:48:47 +02003283 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3284 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3285 conn->dst_type, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003286
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003287 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003288 conn->handle = __le16_to_cpu(ev->handle);
3289 conn->state = BT_CONNECTED;
3290
3291 hci_conn_hold_device(conn);
3292 hci_conn_add_sysfs(conn);
3293
3294 hci_proto_connect_cfm(conn, ev->status);
3295
3296unlock:
3297 hci_dev_unlock(hdev);
3298}
3299
Andre Guedes9aa04c92011-05-26 16:23:51 -03003300static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3301 struct sk_buff *skb)
3302{
Andre Guedese95beb42011-09-26 20:48:35 -03003303 u8 num_reports = skb->data[0];
3304 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003305 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003306
3307 hci_dev_lock(hdev);
3308
Andre Guedese95beb42011-09-26 20:48:35 -03003309 while (num_reports--) {
3310 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003311
Andre Guedes9aa04c92011-05-26 16:23:51 -03003312 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003313
Andre Guedes3c9e9192012-01-10 18:20:50 -03003314 rssi = ev->data[ev->length];
3315 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003316 NULL, rssi, 0, 1, ev->data,
3317 ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003318
Andre Guedese95beb42011-09-26 20:48:35 -03003319 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003320 }
3321
3322 hci_dev_unlock(hdev);
3323}
3324
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003325static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3326 struct sk_buff *skb)
3327{
3328 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3329 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003330 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003331 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003332 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003333
3334 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3335
3336 hci_dev_lock(hdev);
3337
3338 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003339 if (conn == NULL)
3340 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003341
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003342 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3343 if (ltk == NULL)
3344 goto not_found;
3345
3346 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003347 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003348
3349 if (ltk->authenticated)
3350 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003351
3352 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3353
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003354 if (ltk->type & HCI_SMP_STK) {
3355 list_del(&ltk->list);
3356 kfree(ltk);
3357 }
3358
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003359 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003360
3361 return;
3362
3363not_found:
3364 neg.handle = ev->handle;
3365 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3366 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003367}
3368
Ville Tervofcd89c02011-02-10 22:38:47 -03003369static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3370{
3371 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3372
3373 skb_pull(skb, sizeof(*le_ev));
3374
3375 switch (le_ev->subevent) {
3376 case HCI_EV_LE_CONN_COMPLETE:
3377 hci_le_conn_complete_evt(hdev, skb);
3378 break;
3379
Andre Guedes9aa04c92011-05-26 16:23:51 -03003380 case HCI_EV_LE_ADVERTISING_REPORT:
3381 hci_le_adv_report_evt(hdev, skb);
3382 break;
3383
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003384 case HCI_EV_LE_LTK_REQ:
3385 hci_le_ltk_request_evt(hdev, skb);
3386 break;
3387
Ville Tervofcd89c02011-02-10 22:38:47 -03003388 default:
3389 break;
3390 }
3391}
3392
Linus Torvalds1da177e2005-04-16 15:20:36 -07003393void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3394{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003395 struct hci_event_hdr *hdr = (void *) skb->data;
3396 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003397
3398 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3399
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003400 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003401 case HCI_EV_INQUIRY_COMPLETE:
3402 hci_inquiry_complete_evt(hdev, skb);
3403 break;
3404
3405 case HCI_EV_INQUIRY_RESULT:
3406 hci_inquiry_result_evt(hdev, skb);
3407 break;
3408
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003409 case HCI_EV_CONN_COMPLETE:
3410 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003411 break;
3412
Linus Torvalds1da177e2005-04-16 15:20:36 -07003413 case HCI_EV_CONN_REQUEST:
3414 hci_conn_request_evt(hdev, skb);
3415 break;
3416
Linus Torvalds1da177e2005-04-16 15:20:36 -07003417 case HCI_EV_DISCONN_COMPLETE:
3418 hci_disconn_complete_evt(hdev, skb);
3419 break;
3420
Linus Torvalds1da177e2005-04-16 15:20:36 -07003421 case HCI_EV_AUTH_COMPLETE:
3422 hci_auth_complete_evt(hdev, skb);
3423 break;
3424
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003425 case HCI_EV_REMOTE_NAME:
3426 hci_remote_name_evt(hdev, skb);
3427 break;
3428
Linus Torvalds1da177e2005-04-16 15:20:36 -07003429 case HCI_EV_ENCRYPT_CHANGE:
3430 hci_encrypt_change_evt(hdev, skb);
3431 break;
3432
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003433 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3434 hci_change_link_key_complete_evt(hdev, skb);
3435 break;
3436
3437 case HCI_EV_REMOTE_FEATURES:
3438 hci_remote_features_evt(hdev, skb);
3439 break;
3440
3441 case HCI_EV_REMOTE_VERSION:
3442 hci_remote_version_evt(hdev, skb);
3443 break;
3444
3445 case HCI_EV_QOS_SETUP_COMPLETE:
3446 hci_qos_setup_complete_evt(hdev, skb);
3447 break;
3448
3449 case HCI_EV_CMD_COMPLETE:
3450 hci_cmd_complete_evt(hdev, skb);
3451 break;
3452
3453 case HCI_EV_CMD_STATUS:
3454 hci_cmd_status_evt(hdev, skb);
3455 break;
3456
3457 case HCI_EV_ROLE_CHANGE:
3458 hci_role_change_evt(hdev, skb);
3459 break;
3460
3461 case HCI_EV_NUM_COMP_PKTS:
3462 hci_num_comp_pkts_evt(hdev, skb);
3463 break;
3464
3465 case HCI_EV_MODE_CHANGE:
3466 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003467 break;
3468
3469 case HCI_EV_PIN_CODE_REQ:
3470 hci_pin_code_request_evt(hdev, skb);
3471 break;
3472
3473 case HCI_EV_LINK_KEY_REQ:
3474 hci_link_key_request_evt(hdev, skb);
3475 break;
3476
3477 case HCI_EV_LINK_KEY_NOTIFY:
3478 hci_link_key_notify_evt(hdev, skb);
3479 break;
3480
3481 case HCI_EV_CLOCK_OFFSET:
3482 hci_clock_offset_evt(hdev, skb);
3483 break;
3484
Marcel Holtmanna8746412008-07-14 20:13:46 +02003485 case HCI_EV_PKT_TYPE_CHANGE:
3486 hci_pkt_type_change_evt(hdev, skb);
3487 break;
3488
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003489 case HCI_EV_PSCAN_REP_MODE:
3490 hci_pscan_rep_mode_evt(hdev, skb);
3491 break;
3492
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003493 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3494 hci_inquiry_result_with_rssi_evt(hdev, skb);
3495 break;
3496
3497 case HCI_EV_REMOTE_EXT_FEATURES:
3498 hci_remote_ext_features_evt(hdev, skb);
3499 break;
3500
3501 case HCI_EV_SYNC_CONN_COMPLETE:
3502 hci_sync_conn_complete_evt(hdev, skb);
3503 break;
3504
3505 case HCI_EV_SYNC_CONN_CHANGED:
3506 hci_sync_conn_changed_evt(hdev, skb);
3507 break;
3508
Marcel Holtmann04837f62006-07-03 10:02:33 +02003509 case HCI_EV_SNIFF_SUBRATE:
3510 hci_sniff_subrate_evt(hdev, skb);
3511 break;
3512
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003513 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3514 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003515 break;
3516
Marcel Holtmann04936842008-07-14 20:13:48 +02003517 case HCI_EV_IO_CAPA_REQUEST:
3518 hci_io_capa_request_evt(hdev, skb);
3519 break;
3520
Johan Hedberg03b555e2011-01-04 15:40:05 +02003521 case HCI_EV_IO_CAPA_REPLY:
3522 hci_io_capa_reply_evt(hdev, skb);
3523 break;
3524
Johan Hedberga5c29682011-02-19 12:05:57 -03003525 case HCI_EV_USER_CONFIRM_REQUEST:
3526 hci_user_confirm_request_evt(hdev, skb);
3527 break;
3528
Brian Gix1143d452011-11-23 08:28:34 -08003529 case HCI_EV_USER_PASSKEY_REQUEST:
3530 hci_user_passkey_request_evt(hdev, skb);
3531 break;
3532
Marcel Holtmann04936842008-07-14 20:13:48 +02003533 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3534 hci_simple_pair_complete_evt(hdev, skb);
3535 break;
3536
Marcel Holtmann41a96212008-07-14 20:13:48 +02003537 case HCI_EV_REMOTE_HOST_FEATURES:
3538 hci_remote_host_features_evt(hdev, skb);
3539 break;
3540
Ville Tervofcd89c02011-02-10 22:38:47 -03003541 case HCI_EV_LE_META:
3542 hci_le_meta_evt(hdev, skb);
3543 break;
3544
Szymon Janc2763eda2011-03-22 13:12:22 +01003545 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3546 hci_remote_oob_data_request_evt(hdev, skb);
3547 break;
3548
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003549 case HCI_EV_NUM_COMP_BLOCKS:
3550 hci_num_comp_blocks_evt(hdev, skb);
3551 break;
3552
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003553 default:
3554 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003555 break;
3556 }
3557
3558 kfree_skb(skb);
3559 hdev->stat.evt_rx++;
3560}