blob: 3e817fed770670d08597781217bb96b244dfc371 [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);
Johan Hedberg3159d382012-02-24 13:47:56 +0200220
221 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200222}
223
224static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
225{
226 struct hci_rp_read_local_name *rp = (void *) skb->data;
227
228 BT_DBG("%s status 0x%x", hdev->name, rp->status);
229
230 if (rp->status)
231 return;
232
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200233 if (test_bit(HCI_SETUP, &hdev->dev_flags))
234 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200235}
236
237static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
238{
239 __u8 status = *((__u8 *) skb->data);
240 void *sent;
241
242 BT_DBG("%s status 0x%x", hdev->name, status);
243
244 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
245 if (!sent)
246 return;
247
248 if (!status) {
249 __u8 param = *((__u8 *) sent);
250
251 if (param == AUTH_ENABLED)
252 set_bit(HCI_AUTH, &hdev->flags);
253 else
254 clear_bit(HCI_AUTH, &hdev->flags);
255 }
256
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200257 if (test_bit(HCI_MGMT, &hdev->dev_flags))
258 mgmt_auth_enable_complete(hdev, status);
259
Johan Hedberg23bb5762010-12-21 23:01:27 +0200260 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200261}
262
263static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
264{
265 __u8 status = *((__u8 *) skb->data);
266 void *sent;
267
268 BT_DBG("%s status 0x%x", hdev->name, status);
269
270 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
271 if (!sent)
272 return;
273
274 if (!status) {
275 __u8 param = *((__u8 *) sent);
276
277 if (param)
278 set_bit(HCI_ENCRYPT, &hdev->flags);
279 else
280 clear_bit(HCI_ENCRYPT, &hdev->flags);
281 }
282
Johan Hedberg23bb5762010-12-21 23:01:27 +0200283 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200284}
285
286static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
287{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200288 __u8 param, status = *((__u8 *) skb->data);
289 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200290 void *sent;
291
292 BT_DBG("%s status 0x%x", hdev->name, status);
293
294 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
295 if (!sent)
296 return;
297
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200298 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200299
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200300 hci_dev_lock(hdev);
301
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200302 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200303 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200304 hdev->discov_timeout = 0;
305 goto done;
306 }
307
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200308 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
309 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200310
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200311 if (param & SCAN_INQUIRY) {
312 set_bit(HCI_ISCAN, &hdev->flags);
313 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200314 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200315 if (hdev->discov_timeout > 0) {
316 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
317 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
318 to);
319 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200320 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200321 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200322
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 if (param & SCAN_PAGE) {
324 set_bit(HCI_PSCAN, &hdev->flags);
325 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200328 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200329
330done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200331 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200332 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200333}
334
335static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
336{
337 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
338
339 BT_DBG("%s status 0x%x", hdev->name, rp->status);
340
341 if (rp->status)
342 return;
343
344 memcpy(hdev->dev_class, rp->dev_class, 3);
345
346 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
347 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
348}
349
350static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
351{
352 __u8 status = *((__u8 *) skb->data);
353 void *sent;
354
355 BT_DBG("%s status 0x%x", hdev->name, status);
356
357 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
358 if (!sent)
359 return;
360
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100361 hci_dev_lock(hdev);
362
363 if (status == 0)
364 memcpy(hdev->dev_class, sent, 3);
365
366 if (test_bit(HCI_MGMT, &hdev->dev_flags))
367 mgmt_set_class_of_dev_complete(hdev, sent, status);
368
369 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200370}
371
372static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
373{
374 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200376
377 BT_DBG("%s status 0x%x", hdev->name, rp->status);
378
379 if (rp->status)
380 return;
381
382 setting = __le16_to_cpu(rp->voice_setting);
383
Marcel Holtmannf383f272008-07-14 20:13:47 +0200384 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200385 return;
386
387 hdev->voice_setting = setting;
388
389 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
390
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200391 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200393}
394
395static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
396{
397 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200398 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 void *sent;
400
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200401 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Marcel Holtmannf383f272008-07-14 20:13:47 +0200403 if (status)
404 return;
405
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200406 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
407 if (!sent)
408 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Marcel Holtmannf383f272008-07-14 20:13:47 +0200412 if (hdev->voice_setting == setting)
413 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Marcel Holtmannf383f272008-07-14 20:13:47 +0200415 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Marcel Holtmannf383f272008-07-14 20:13:47 +0200417 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
418
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200419 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200420 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421}
422
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200423static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200425 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200427 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428
Johan Hedberg23bb5762010-12-21 23:01:27 +0200429 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430}
431
Marcel Holtmann333140b2008-07-14 20:13:48 +0200432static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
433{
434 __u8 status = *((__u8 *) skb->data);
435 void *sent;
436
437 BT_DBG("%s status 0x%x", hdev->name, status);
438
Marcel Holtmann333140b2008-07-14 20:13:48 +0200439 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
440 if (!sent)
441 return;
442
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200443 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200444 mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status);
445 else if (!status) {
446 if (*((u8 *) sent))
447 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
448 else
449 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
450 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200451}
452
Johan Hedbergd5859e22011-01-25 01:19:58 +0200453static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
454{
455 if (hdev->features[6] & LMP_EXT_INQ)
456 return 2;
457
458 if (hdev->features[3] & LMP_RSSI_INQ)
459 return 1;
460
461 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
462 hdev->lmp_subver == 0x0757)
463 return 1;
464
465 if (hdev->manufacturer == 15) {
466 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
467 return 1;
468 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
469 return 1;
470 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
471 return 1;
472 }
473
474 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
475 hdev->lmp_subver == 0x1805)
476 return 1;
477
478 return 0;
479}
480
481static void hci_setup_inquiry_mode(struct hci_dev *hdev)
482{
483 u8 mode;
484
485 mode = hci_get_inquiry_mode(hdev);
486
487 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
488}
489
490static void hci_setup_event_mask(struct hci_dev *hdev)
491{
492 /* The second byte is 0xff instead of 0x9f (two reserved bits
493 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
494 * command otherwise */
495 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
496
Ville Tervo6de6c182011-05-27 11:16:21 +0300497 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
498 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200499 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300500 return;
501
502 events[4] |= 0x01; /* Flow Specification Complete */
503 events[4] |= 0x02; /* Inquiry Result with RSSI */
504 events[4] |= 0x04; /* Read Remote Extended Features Complete */
505 events[5] |= 0x08; /* Synchronous Connection Complete */
506 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200507
508 if (hdev->features[3] & LMP_RSSI_INQ)
509 events[4] |= 0x04; /* Inquiry Result with RSSI */
510
511 if (hdev->features[5] & LMP_SNIFF_SUBR)
512 events[5] |= 0x20; /* Sniff Subrating */
513
514 if (hdev->features[5] & LMP_PAUSE_ENC)
515 events[5] |= 0x80; /* Encryption Key Refresh Complete */
516
517 if (hdev->features[6] & LMP_EXT_INQ)
518 events[5] |= 0x40; /* Extended Inquiry Result */
519
520 if (hdev->features[6] & LMP_NO_FLUSH)
521 events[7] |= 0x01; /* Enhanced Flush Complete */
522
523 if (hdev->features[7] & LMP_LSTO)
524 events[6] |= 0x80; /* Link Supervision Timeout Changed */
525
526 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
527 events[6] |= 0x01; /* IO Capability Request */
528 events[6] |= 0x02; /* IO Capability Response */
529 events[6] |= 0x04; /* User Confirmation Request */
530 events[6] |= 0x08; /* User Passkey Request */
531 events[6] |= 0x10; /* Remote OOB Data Request */
532 events[6] |= 0x20; /* Simple Pairing Complete */
533 events[7] |= 0x04; /* User Passkey Notification */
534 events[7] |= 0x08; /* Keypress Notification */
535 events[7] |= 0x10; /* Remote Host Supported
536 * Features Notification */
537 }
538
539 if (hdev->features[4] & LMP_LE)
540 events[7] |= 0x20; /* LE Meta-Event */
541
542 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
543}
544
Andre Guedese6100a22011-06-30 19:20:54 -0300545static void hci_set_le_support(struct hci_dev *hdev)
546{
547 struct hci_cp_write_le_host_supported cp;
548
549 memset(&cp, 0, sizeof(cp));
550
Johan Hedberg06199cf2012-02-22 16:37:11 +0200551 if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
Andre Guedese6100a22011-06-30 19:20:54 -0300552 cp.le = 1;
553 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
554 }
555
556 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
557}
558
Johan Hedbergd5859e22011-01-25 01:19:58 +0200559static void hci_setup(struct hci_dev *hdev)
560{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200561 if (hdev->dev_type != HCI_BREDR)
562 return;
563
Johan Hedbergd5859e22011-01-25 01:19:58 +0200564 hci_setup_event_mask(hdev);
565
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200566 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200567 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
568
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200569 if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
570 test_bit(HCI_MGMT, &hdev->dev_flags)) {
571 struct hci_cp_write_local_name cp;
572
573 memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
574 hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp);
575 }
576
Johan Hedberg54d04db2012-02-22 15:47:48 +0200577 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
578 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
579 u8 mode = 0x01;
580 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
581 sizeof(mode), &mode);
582 } else {
583 struct hci_cp_write_eir cp;
584
585 memset(hdev->eir, 0, sizeof(hdev->eir));
586 memset(&cp, 0, sizeof(cp));
587
588 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
589 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200590 }
591
592 if (hdev->features[3] & LMP_RSSI_INQ)
593 hci_setup_inquiry_mode(hdev);
594
595 if (hdev->features[7] & LMP_INQ_TX_PWR)
596 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300597
598 if (hdev->features[7] & LMP_EXTFEATURES) {
599 struct hci_cp_read_local_ext_features cp;
600
601 cp.page = 0x01;
602 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
603 sizeof(cp), &cp);
604 }
Andre Guedese6100a22011-06-30 19:20:54 -0300605
Johan Hedberg47990ea2012-02-22 11:58:37 +0200606 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
607 u8 enable = 1;
608 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE,
609 sizeof(enable), &enable);
610 }
611
Andre Guedese6100a22011-06-30 19:20:54 -0300612 if (hdev->features[4] & LMP_LE)
613 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200614}
615
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200616static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
617{
618 struct hci_rp_read_local_version *rp = (void *) skb->data;
619
620 BT_DBG("%s status 0x%x", hdev->name, rp->status);
621
622 if (rp->status)
623 return;
624
625 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200626 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200627 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200628 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200629 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200630
631 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
632 hdev->manufacturer,
633 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200634
635 if (test_bit(HCI_INIT, &hdev->flags))
636 hci_setup(hdev);
637}
638
639static void hci_setup_link_policy(struct hci_dev *hdev)
640{
641 u16 link_policy = 0;
642
643 if (hdev->features[0] & LMP_RSWITCH)
644 link_policy |= HCI_LP_RSWITCH;
645 if (hdev->features[0] & LMP_HOLD)
646 link_policy |= HCI_LP_HOLD;
647 if (hdev->features[0] & LMP_SNIFF)
648 link_policy |= HCI_LP_SNIFF;
649 if (hdev->features[1] & LMP_PARK)
650 link_policy |= HCI_LP_PARK;
651
652 link_policy = cpu_to_le16(link_policy);
653 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
654 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200655}
656
657static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
658{
659 struct hci_rp_read_local_commands *rp = (void *) skb->data;
660
661 BT_DBG("%s status 0x%x", hdev->name, rp->status);
662
663 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200664 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200665
666 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200667
668 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
669 hci_setup_link_policy(hdev);
670
671done:
672 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200673}
674
675static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
676{
677 struct hci_rp_read_local_features *rp = (void *) skb->data;
678
679 BT_DBG("%s status 0x%x", hdev->name, rp->status);
680
681 if (rp->status)
682 return;
683
684 memcpy(hdev->features, rp->features, 8);
685
686 /* Adjust default settings according to features
687 * supported by device. */
688
689 if (hdev->features[0] & LMP_3SLOT)
690 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
691
692 if (hdev->features[0] & LMP_5SLOT)
693 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
694
695 if (hdev->features[1] & LMP_HV2) {
696 hdev->pkt_type |= (HCI_HV2);
697 hdev->esco_type |= (ESCO_HV2);
698 }
699
700 if (hdev->features[1] & LMP_HV3) {
701 hdev->pkt_type |= (HCI_HV3);
702 hdev->esco_type |= (ESCO_HV3);
703 }
704
705 if (hdev->features[3] & LMP_ESCO)
706 hdev->esco_type |= (ESCO_EV3);
707
708 if (hdev->features[4] & LMP_EV4)
709 hdev->esco_type |= (ESCO_EV4);
710
711 if (hdev->features[4] & LMP_EV5)
712 hdev->esco_type |= (ESCO_EV5);
713
Marcel Holtmannefc76882009-02-06 09:13:37 +0100714 if (hdev->features[5] & LMP_EDR_ESCO_2M)
715 hdev->esco_type |= (ESCO_2EV3);
716
717 if (hdev->features[5] & LMP_EDR_ESCO_3M)
718 hdev->esco_type |= (ESCO_3EV3);
719
720 if (hdev->features[5] & LMP_EDR_3S_ESCO)
721 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
722
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200723 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
724 hdev->features[0], hdev->features[1],
725 hdev->features[2], hdev->features[3],
726 hdev->features[4], hdev->features[5],
727 hdev->features[6], hdev->features[7]);
728}
729
Andre Guedes971e3a42011-06-30 19:20:52 -0300730static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
731 struct sk_buff *skb)
732{
733 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
734
735 BT_DBG("%s status 0x%x", hdev->name, rp->status);
736
737 if (rp->status)
738 return;
739
Andre Guedesb5b32b62011-12-30 10:34:04 -0300740 switch (rp->page) {
741 case 0:
742 memcpy(hdev->features, rp->features, 8);
743 break;
744 case 1:
745 memcpy(hdev->host_features, rp->features, 8);
746 break;
747 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300748
749 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
750}
751
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200752static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
753 struct sk_buff *skb)
754{
755 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
756
757 BT_DBG("%s status 0x%x", hdev->name, rp->status);
758
759 if (rp->status)
760 return;
761
762 hdev->flow_ctl_mode = rp->mode;
763
764 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
765}
766
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200767static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
768{
769 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
770
771 BT_DBG("%s status 0x%x", hdev->name, rp->status);
772
773 if (rp->status)
774 return;
775
776 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
777 hdev->sco_mtu = rp->sco_mtu;
778 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
779 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
780
781 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
782 hdev->sco_mtu = 64;
783 hdev->sco_pkts = 8;
784 }
785
786 hdev->acl_cnt = hdev->acl_pkts;
787 hdev->sco_cnt = hdev->sco_pkts;
788
789 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
790 hdev->acl_mtu, hdev->acl_pkts,
791 hdev->sco_mtu, hdev->sco_pkts);
792}
793
794static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
795{
796 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
797
798 BT_DBG("%s status 0x%x", hdev->name, rp->status);
799
800 if (!rp->status)
801 bacpy(&hdev->bdaddr, &rp->bdaddr);
802
Johan Hedberg23bb5762010-12-21 23:01:27 +0200803 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
804}
805
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200806static void hci_cc_read_data_block_size(struct hci_dev *hdev,
807 struct sk_buff *skb)
808{
809 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
810
811 BT_DBG("%s status 0x%x", hdev->name, rp->status);
812
813 if (rp->status)
814 return;
815
816 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
817 hdev->block_len = __le16_to_cpu(rp->block_len);
818 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
819
820 hdev->block_cnt = hdev->num_blocks;
821
822 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
823 hdev->block_cnt, hdev->block_len);
824
825 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
826}
827
Johan Hedberg23bb5762010-12-21 23:01:27 +0200828static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
829{
830 __u8 status = *((__u8 *) skb->data);
831
832 BT_DBG("%s status 0x%x", hdev->name, status);
833
834 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200835}
836
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300837static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
838 struct sk_buff *skb)
839{
840 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
841
842 BT_DBG("%s status 0x%x", hdev->name, rp->status);
843
844 if (rp->status)
845 return;
846
847 hdev->amp_status = rp->amp_status;
848 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
849 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
850 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
851 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
852 hdev->amp_type = rp->amp_type;
853 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
854 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
855 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
856 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
857
858 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
859}
860
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200861static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
862 struct sk_buff *skb)
863{
864 __u8 status = *((__u8 *) skb->data);
865
866 BT_DBG("%s status 0x%x", hdev->name, status);
867
868 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
869}
870
Johan Hedbergd5859e22011-01-25 01:19:58 +0200871static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
872{
873 __u8 status = *((__u8 *) skb->data);
874
875 BT_DBG("%s status 0x%x", hdev->name, status);
876
877 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
878}
879
880static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
881 struct sk_buff *skb)
882{
883 __u8 status = *((__u8 *) skb->data);
884
885 BT_DBG("%s status 0x%x", hdev->name, status);
886
887 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
888}
889
890static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
891 struct sk_buff *skb)
892{
893 __u8 status = *((__u8 *) skb->data);
894
895 BT_DBG("%s status 0x%x", hdev->name, status);
896
897 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
898}
899
900static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
901{
902 __u8 status = *((__u8 *) skb->data);
903
904 BT_DBG("%s status 0x%x", hdev->name, status);
905
906 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
907}
908
Johan Hedberg980e1a52011-01-22 06:10:07 +0200909static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
910{
911 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
912 struct hci_cp_pin_code_reply *cp;
913 struct hci_conn *conn;
914
915 BT_DBG("%s status 0x%x", hdev->name, rp->status);
916
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200917 hci_dev_lock(hdev);
918
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200919 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200920 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200921
922 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200923 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200924
925 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
926 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200927 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200928
929 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
930 if (conn)
931 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200932
933unlock:
934 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200935}
936
937static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
938{
939 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
940
941 BT_DBG("%s status 0x%x", hdev->name, rp->status);
942
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200943 hci_dev_lock(hdev);
944
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200945 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200946 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200947 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200948
949 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200950}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200951
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300952static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
953 struct sk_buff *skb)
954{
955 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
956
957 BT_DBG("%s status 0x%x", hdev->name, rp->status);
958
959 if (rp->status)
960 return;
961
962 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
963 hdev->le_pkts = rp->le_max_pkt;
964
965 hdev->le_cnt = hdev->le_pkts;
966
967 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
968
969 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
970}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200971
Johan Hedberga5c29682011-02-19 12:05:57 -0300972static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
973{
974 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
975
976 BT_DBG("%s status 0x%x", hdev->name, rp->status);
977
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200978 hci_dev_lock(hdev);
979
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200980 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200981 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
982 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200983
984 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300985}
986
987static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
988 struct sk_buff *skb)
989{
990 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
991
992 BT_DBG("%s status 0x%x", hdev->name, rp->status);
993
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200994 hci_dev_lock(hdev);
995
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200996 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200997 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200998 ACL_LINK, 0,
Johan Hedberga5c29682011-02-19 12:05:57 -0300999 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001000
1001 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -03001002}
1003
Brian Gix1143d452011-11-23 08:28:34 -08001004static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
1005{
1006 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1007
1008 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1009
1010 hci_dev_lock(hdev);
1011
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001012 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001013 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1014 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001015
1016 hci_dev_unlock(hdev);
1017}
1018
1019static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1020 struct sk_buff *skb)
1021{
1022 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1023
1024 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1025
1026 hci_dev_lock(hdev);
1027
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001028 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001029 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001030 ACL_LINK, 0,
Brian Gix1143d452011-11-23 08:28:34 -08001031 rp->status);
1032
1033 hci_dev_unlock(hdev);
1034}
1035
Szymon Jancc35938b2011-03-22 13:12:21 +01001036static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1037 struct sk_buff *skb)
1038{
1039 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1040
1041 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1042
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001043 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001044 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001045 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001046 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001047}
1048
Andre Guedes07f7fa52011-12-02 21:13:31 +09001049static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1050{
1051 __u8 status = *((__u8 *) skb->data);
1052
1053 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001054
1055 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001056
1057 if (status) {
1058 hci_dev_lock(hdev);
1059 mgmt_start_discovery_failed(hdev, status);
1060 hci_dev_unlock(hdev);
1061 return;
1062 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001063}
1064
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001065static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1066 struct sk_buff *skb)
1067{
1068 struct hci_cp_le_set_scan_enable *cp;
1069 __u8 status = *((__u8 *) skb->data);
1070
1071 BT_DBG("%s status 0x%x", hdev->name, status);
1072
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001073 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1074 if (!cp)
1075 return;
1076
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001077 switch (cp->enable) {
1078 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001079 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1080
Andre Guedes3fd24152012-02-03 17:48:01 -03001081 if (status) {
1082 hci_dev_lock(hdev);
1083 mgmt_start_discovery_failed(hdev, status);
1084 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001085 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001086 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001087
Andre Guedesd23264a2011-11-25 20:53:38 -03001088 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1089
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001090 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001091
1092 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001093 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001094 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001095 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001096 break;
1097
1098 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001099 if (status)
1100 return;
1101
Andre Guedesd23264a2011-11-25 20:53:38 -03001102 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1103
Andre Guedesd0843292012-01-02 19:18:11 -03001104 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001105
1106 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1107 mgmt_interleaved_discovery(hdev);
1108 } else {
1109 hci_dev_lock(hdev);
1110 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1111 hci_dev_unlock(hdev);
1112 }
1113
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001114 break;
1115
1116 default:
1117 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1118 break;
Andre Guedes35815082011-05-26 16:23:53 -03001119 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001120}
1121
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001122static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1123{
1124 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1125
1126 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1127
1128 if (rp->status)
1129 return;
1130
1131 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1132}
1133
1134static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1135{
1136 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1137
1138 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1139
1140 if (rp->status)
1141 return;
1142
1143 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1144}
1145
Andre Guedesf9b49302011-06-30 19:20:53 -03001146static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1147 struct sk_buff *skb)
1148{
1149 struct hci_cp_read_local_ext_features cp;
Johan Hedberg06199cf2012-02-22 16:37:11 +02001150 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001151 __u8 status = *((__u8 *) skb->data);
1152
1153 BT_DBG("%s status 0x%x", hdev->name, status);
1154
Johan Hedberg06199cf2012-02-22 16:37:11 +02001155 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
1156 if (sent && test_bit(HCI_MGMT, &hdev->dev_flags))
1157 mgmt_le_enable_complete(hdev, sent->le, status);
1158
Andre Guedesf9b49302011-06-30 19:20:53 -03001159 if (status)
1160 return;
1161
1162 cp.page = 0x01;
1163 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1164}
1165
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001166static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1167{
1168 BT_DBG("%s status 0x%x", hdev->name, status);
1169
1170 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001171 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001172 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001173 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001174 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001175 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001176 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001177 return;
1178 }
1179
Andre Guedes89352e72011-11-04 14:16:53 -03001180 set_bit(HCI_INQUIRY, &hdev->flags);
1181
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001182 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001183 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001184 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001185}
1186
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1188{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001189 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001192 BT_DBG("%s status 0x%x", hdev->name, status);
1193
1194 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 if (!cp)
1196 return;
1197
1198 hci_dev_lock(hdev);
1199
1200 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1201
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001202 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
1204 if (status) {
1205 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001206 if (status != 0x0c || conn->attempt > 2) {
1207 conn->state = BT_CLOSED;
1208 hci_proto_connect_cfm(conn, status);
1209 hci_conn_del(conn);
1210 } else
1211 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 }
1213 } else {
1214 if (!conn) {
1215 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1216 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001217 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 conn->link_mode |= HCI_LM_MASTER;
1219 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001220 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 }
1222 }
1223
1224 hci_dev_unlock(hdev);
1225}
1226
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001227static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001229 struct hci_cp_add_sco *cp;
1230 struct hci_conn *acl, *sco;
1231 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001233 BT_DBG("%s status 0x%x", hdev->name, status);
1234
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001235 if (!status)
1236 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001238 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1239 if (!cp)
1240 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001242 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001244 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001245
1246 hci_dev_lock(hdev);
1247
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001248 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001249 if (acl) {
1250 sco = acl->link;
1251 if (sco) {
1252 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001253
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001254 hci_proto_connect_cfm(sco, status);
1255 hci_conn_del(sco);
1256 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001257 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001258
1259 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260}
1261
Marcel Holtmannf8558552008-07-14 20:13:49 +02001262static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1263{
1264 struct hci_cp_auth_requested *cp;
1265 struct hci_conn *conn;
1266
1267 BT_DBG("%s status 0x%x", hdev->name, status);
1268
1269 if (!status)
1270 return;
1271
1272 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1273 if (!cp)
1274 return;
1275
1276 hci_dev_lock(hdev);
1277
1278 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1279 if (conn) {
1280 if (conn->state == BT_CONFIG) {
1281 hci_proto_connect_cfm(conn, status);
1282 hci_conn_put(conn);
1283 }
1284 }
1285
1286 hci_dev_unlock(hdev);
1287}
1288
1289static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1290{
1291 struct hci_cp_set_conn_encrypt *cp;
1292 struct hci_conn *conn;
1293
1294 BT_DBG("%s status 0x%x", hdev->name, status);
1295
1296 if (!status)
1297 return;
1298
1299 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1300 if (!cp)
1301 return;
1302
1303 hci_dev_lock(hdev);
1304
1305 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1306 if (conn) {
1307 if (conn->state == BT_CONFIG) {
1308 hci_proto_connect_cfm(conn, status);
1309 hci_conn_put(conn);
1310 }
1311 }
1312
1313 hci_dev_unlock(hdev);
1314}
1315
Johan Hedberg127178d2010-11-18 22:22:29 +02001316static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001317 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001318{
Johan Hedberg392599b2010-11-18 22:22:28 +02001319 if (conn->state != BT_CONFIG || !conn->out)
1320 return 0;
1321
Johan Hedberg765c2a92011-01-19 12:06:52 +05301322 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001323 return 0;
1324
1325 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001326 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001327 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001328 conn->pending_sec_level != BT_SECURITY_HIGH &&
1329 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001330 return 0;
1331
Johan Hedberg392599b2010-11-18 22:22:28 +02001332 return 1;
1333}
1334
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001335static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1336{
1337 struct hci_cp_remote_name_req cp;
1338
1339 memset(&cp, 0, sizeof(cp));
1340
1341 bacpy(&cp.bdaddr, &e->data.bdaddr);
1342 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1343 cp.pscan_mode = e->data.pscan_mode;
1344 cp.clock_offset = e->data.clock_offset;
1345
1346 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1347}
1348
Johan Hedbergb644ba32012-01-17 21:48:47 +02001349static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001350{
1351 struct discovery_state *discov = &hdev->discovery;
1352 struct inquiry_entry *e;
1353
Johan Hedbergb644ba32012-01-17 21:48:47 +02001354 if (list_empty(&discov->resolve))
1355 return false;
1356
1357 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1358 if (hci_resolve_name(hdev, e) == 0) {
1359 e->name_state = NAME_PENDING;
1360 return true;
1361 }
1362
1363 return false;
1364}
1365
1366static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1367 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1368{
1369 struct discovery_state *discov = &hdev->discovery;
1370 struct inquiry_entry *e;
1371
1372 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Johan Hedberg08c79b62012-02-23 22:31:51 +02001373 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0,
Johan Hedbergb644ba32012-01-17 21:48:47 +02001374 name, name_len, conn->dev_class);
1375
1376 if (discov->state == DISCOVERY_STOPPED)
1377 return;
1378
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001379 if (discov->state == DISCOVERY_STOPPING)
1380 goto discov_complete;
1381
1382 if (discov->state != DISCOVERY_RESOLVING)
1383 return;
1384
1385 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1386 if (e) {
1387 e->name_state = NAME_KNOWN;
1388 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001389 if (name)
1390 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1391 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001392 }
1393
Johan Hedbergb644ba32012-01-17 21:48:47 +02001394 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001395 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001396
1397discov_complete:
1398 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1399}
1400
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001401static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1402{
Johan Hedberg127178d2010-11-18 22:22:29 +02001403 struct hci_cp_remote_name_req *cp;
1404 struct hci_conn *conn;
1405
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001406 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001407
1408 /* If successful wait for the name req complete event before
1409 * checking for the need to do authentication */
1410 if (!status)
1411 return;
1412
1413 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1414 if (!cp)
1415 return;
1416
1417 hci_dev_lock(hdev);
1418
1419 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001420
1421 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1422 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1423
Johan Hedberg79c6c702011-04-28 11:28:55 -07001424 if (!conn)
1425 goto unlock;
1426
1427 if (!hci_outgoing_auth_needed(hdev, conn))
1428 goto unlock;
1429
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001430 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001431 struct hci_cp_auth_requested cp;
1432 cp.handle = __cpu_to_le16(conn->handle);
1433 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1434 }
1435
Johan Hedberg79c6c702011-04-28 11:28:55 -07001436unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001437 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001438}
1439
Marcel Holtmann769be972008-07-14 20:13:49 +02001440static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1441{
1442 struct hci_cp_read_remote_features *cp;
1443 struct hci_conn *conn;
1444
1445 BT_DBG("%s status 0x%x", hdev->name, status);
1446
1447 if (!status)
1448 return;
1449
1450 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1451 if (!cp)
1452 return;
1453
1454 hci_dev_lock(hdev);
1455
1456 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1457 if (conn) {
1458 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001459 hci_proto_connect_cfm(conn, status);
1460 hci_conn_put(conn);
1461 }
1462 }
1463
1464 hci_dev_unlock(hdev);
1465}
1466
1467static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1468{
1469 struct hci_cp_read_remote_ext_features *cp;
1470 struct hci_conn *conn;
1471
1472 BT_DBG("%s status 0x%x", hdev->name, status);
1473
1474 if (!status)
1475 return;
1476
1477 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1478 if (!cp)
1479 return;
1480
1481 hci_dev_lock(hdev);
1482
1483 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1484 if (conn) {
1485 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001486 hci_proto_connect_cfm(conn, status);
1487 hci_conn_put(conn);
1488 }
1489 }
1490
1491 hci_dev_unlock(hdev);
1492}
1493
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001494static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1495{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001496 struct hci_cp_setup_sync_conn *cp;
1497 struct hci_conn *acl, *sco;
1498 __u16 handle;
1499
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001500 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001501
1502 if (!status)
1503 return;
1504
1505 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1506 if (!cp)
1507 return;
1508
1509 handle = __le16_to_cpu(cp->handle);
1510
1511 BT_DBG("%s handle %d", hdev->name, handle);
1512
1513 hci_dev_lock(hdev);
1514
1515 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001516 if (acl) {
1517 sco = acl->link;
1518 if (sco) {
1519 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001520
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001521 hci_proto_connect_cfm(sco, status);
1522 hci_conn_del(sco);
1523 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001524 }
1525
1526 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001527}
1528
1529static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1530{
1531 struct hci_cp_sniff_mode *cp;
1532 struct hci_conn *conn;
1533
1534 BT_DBG("%s status 0x%x", hdev->name, status);
1535
1536 if (!status)
1537 return;
1538
1539 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1540 if (!cp)
1541 return;
1542
1543 hci_dev_lock(hdev);
1544
1545 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001546 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001547 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001548
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001549 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001550 hci_sco_setup(conn, status);
1551 }
1552
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001553 hci_dev_unlock(hdev);
1554}
1555
1556static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1557{
1558 struct hci_cp_exit_sniff_mode *cp;
1559 struct hci_conn *conn;
1560
1561 BT_DBG("%s status 0x%x", hdev->name, status);
1562
1563 if (!status)
1564 return;
1565
1566 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1567 if (!cp)
1568 return;
1569
1570 hci_dev_lock(hdev);
1571
1572 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001573 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001574 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001575
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001576 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001577 hci_sco_setup(conn, status);
1578 }
1579
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001580 hci_dev_unlock(hdev);
1581}
1582
Johan Hedberg88c3df12012-02-09 14:27:38 +02001583static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1584{
1585 struct hci_cp_disconnect *cp;
1586 struct hci_conn *conn;
1587
1588 if (!status)
1589 return;
1590
1591 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1592 if (!cp)
1593 return;
1594
1595 hci_dev_lock(hdev);
1596
1597 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1598 if (conn)
1599 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1600 conn->dst_type, status);
1601
1602 hci_dev_unlock(hdev);
1603}
1604
Ville Tervofcd89c02011-02-10 22:38:47 -03001605static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1606{
1607 struct hci_cp_le_create_conn *cp;
1608 struct hci_conn *conn;
1609
1610 BT_DBG("%s status 0x%x", hdev->name, status);
1611
1612 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1613 if (!cp)
1614 return;
1615
1616 hci_dev_lock(hdev);
1617
1618 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1619
1620 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1621 conn);
1622
1623 if (status) {
1624 if (conn && conn->state == BT_CONNECT) {
1625 conn->state = BT_CLOSED;
1626 hci_proto_connect_cfm(conn, status);
1627 hci_conn_del(conn);
1628 }
1629 } else {
1630 if (!conn) {
1631 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001632 if (conn) {
1633 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001634 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001635 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001636 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001637 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001638 }
1639 }
1640
1641 hci_dev_unlock(hdev);
1642}
1643
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001644static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1645{
1646 BT_DBG("%s status 0x%x", hdev->name, status);
1647}
1648
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001649static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1650{
1651 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001652 struct discovery_state *discov = &hdev->discovery;
1653 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001654
1655 BT_DBG("%s status %d", hdev->name, status);
1656
Johan Hedberg23bb5762010-12-21 23:01:27 +02001657 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001658
1659 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001660
1661 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1662 return;
1663
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001664 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001665 return;
1666
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001667 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001668
Andre Guedes343f9352012-02-17 20:39:37 -03001669 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001670 goto unlock;
1671
1672 if (list_empty(&discov->resolve)) {
1673 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1674 goto unlock;
1675 }
1676
1677 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1678 if (e && hci_resolve_name(hdev, e) == 0) {
1679 e->name_state = NAME_PENDING;
1680 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1681 } else {
1682 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1683 }
1684
1685unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001686 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001687}
1688
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1690{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001691 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001692 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 int num_rsp = *((__u8 *) skb->data);
1694
1695 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1696
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001697 if (!num_rsp)
1698 return;
1699
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001701
Johan Hedberge17acd42011-03-30 23:57:16 +03001702 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001703 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001704
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 bacpy(&data.bdaddr, &info->bdaddr);
1706 data.pscan_rep_mode = info->pscan_rep_mode;
1707 data.pscan_period_mode = info->pscan_period_mode;
1708 data.pscan_mode = info->pscan_mode;
1709 memcpy(data.dev_class, info->dev_class, 3);
1710 data.clock_offset = info->clock_offset;
1711 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001712 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001713
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001714 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001715 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001716 info->dev_class, 0, !name_known, ssp,
Andre Guedes7d262f82012-01-10 18:20:49 -03001717 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001719
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 hci_dev_unlock(hdev);
1721}
1722
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001723static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001725 struct hci_ev_conn_complete *ev = (void *) skb->data;
1726 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001728 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001729
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001731
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001732 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001733 if (!conn) {
1734 if (ev->link_type != SCO_LINK)
1735 goto unlock;
1736
1737 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1738 if (!conn)
1739 goto unlock;
1740
1741 conn->type = SCO_LINK;
1742 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001743
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001744 if (!ev->status) {
1745 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001746
1747 if (conn->type == ACL_LINK) {
1748 conn->state = BT_CONFIG;
1749 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001750 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001751 } else
1752 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001753
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001754 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001755 hci_conn_add_sysfs(conn);
1756
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001757 if (test_bit(HCI_AUTH, &hdev->flags))
1758 conn->link_mode |= HCI_LM_AUTH;
1759
1760 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1761 conn->link_mode |= HCI_LM_ENCRYPT;
1762
1763 /* Get remote features */
1764 if (conn->type == ACL_LINK) {
1765 struct hci_cp_read_remote_features cp;
1766 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001767 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1768 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001769 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001770
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001771 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001772 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001773 struct hci_cp_change_conn_ptype cp;
1774 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001775 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1776 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1777 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001778 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001779 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001780 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001781 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001782 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001783 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001784 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001785
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001786 if (conn->type == ACL_LINK)
1787 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001788
Marcel Holtmann769be972008-07-14 20:13:49 +02001789 if (ev->status) {
1790 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001791 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001792 } else if (ev->link_type != ACL_LINK)
1793 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001794
1795unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001797
1798 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799}
1800
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1802{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001803 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 int mask = hdev->link_mode;
1805
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001806 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1807 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808
1809 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1810
Szymon Janc138d22e2011-02-17 16:44:23 +01001811 if ((mask & HCI_LM_ACCEPT) &&
1812 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001814 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
1817 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001818
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001819 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1820 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001821 memcpy(ie->data.dev_class, ev->dev_class, 3);
1822
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1824 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001825 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1826 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001827 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 hci_dev_unlock(hdev);
1829 return;
1830 }
1831 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001832
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 memcpy(conn->dev_class, ev->dev_class, 3);
1834 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001835
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 hci_dev_unlock(hdev);
1837
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001838 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1839 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001841 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001843 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1844 cp.role = 0x00; /* Become master */
1845 else
1846 cp.role = 0x01; /* Remain slave */
1847
1848 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1849 sizeof(cp), &cp);
1850 } else {
1851 struct hci_cp_accept_sync_conn_req cp;
1852
1853 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001854 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001855
1856 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1857 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1858 cp.max_latency = cpu_to_le16(0xffff);
1859 cp.content_format = cpu_to_le16(hdev->voice_setting);
1860 cp.retrans_effort = 0xff;
1861
1862 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1863 sizeof(cp), &cp);
1864 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 } else {
1866 /* Connection rejected */
1867 struct hci_cp_reject_conn_req cp;
1868
1869 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001870 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001871 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872 }
1873}
1874
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1876{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001877 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001878 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879
1880 BT_DBG("%s status %d", hdev->name, ev->status);
1881
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 hci_dev_lock(hdev);
1883
Marcel Holtmann04837f62006-07-03 10:02:33 +02001884 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001885 if (!conn)
1886 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001887
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001888 if (ev->status == 0)
1889 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890
Johan Hedbergb644ba32012-01-17 21:48:47 +02001891 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1892 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001893 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001894 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1895 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001896 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001897 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001898 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001899 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001900
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001901 if (ev->status == 0) {
1902 hci_proto_disconn_cfm(conn, ev->reason);
1903 hci_conn_del(conn);
1904 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001905
1906unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 hci_dev_unlock(hdev);
1908}
1909
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001910static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1911{
1912 struct hci_ev_auth_complete *ev = (void *) skb->data;
1913 struct hci_conn *conn;
1914
1915 BT_DBG("%s status %d", hdev->name, ev->status);
1916
1917 hci_dev_lock(hdev);
1918
1919 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001920 if (!conn)
1921 goto unlock;
1922
1923 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001924 if (!hci_conn_ssp_enabled(conn) &&
1925 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001926 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001927 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001928 conn->link_mode |= HCI_LM_AUTH;
1929 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001930 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001931 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001932 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
1933 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001934 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001935
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001936 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1937 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001938
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001939 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001940 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001941 struct hci_cp_set_conn_encrypt cp;
1942 cp.handle = ev->handle;
1943 cp.encrypt = 0x01;
1944 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1945 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001946 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001947 conn->state = BT_CONNECTED;
1948 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001949 hci_conn_put(conn);
1950 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001951 } else {
1952 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001953
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001954 hci_conn_hold(conn);
1955 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1956 hci_conn_put(conn);
1957 }
1958
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001959 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001960 if (!ev->status) {
1961 struct hci_cp_set_conn_encrypt cp;
1962 cp.handle = ev->handle;
1963 cp.encrypt = 0x01;
1964 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1965 &cp);
1966 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001967 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001968 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001969 }
1970 }
1971
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001972unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001973 hci_dev_unlock(hdev);
1974}
1975
1976static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1977{
Johan Hedberg127178d2010-11-18 22:22:29 +02001978 struct hci_ev_remote_name *ev = (void *) skb->data;
1979 struct hci_conn *conn;
1980
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001981 BT_DBG("%s", hdev->name);
1982
1983 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001984
1985 hci_dev_lock(hdev);
1986
1987 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001988
1989 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1990 goto check_auth;
1991
1992 if (ev->status == 0)
1993 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1994 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1995 else
1996 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1997
1998check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001999 if (!conn)
2000 goto unlock;
2001
2002 if (!hci_outgoing_auth_needed(hdev, conn))
2003 goto unlock;
2004
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002005 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002006 struct hci_cp_auth_requested cp;
2007 cp.handle = __cpu_to_le16(conn->handle);
2008 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2009 }
2010
Johan Hedberg79c6c702011-04-28 11:28:55 -07002011unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002012 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002013}
2014
2015static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2016{
2017 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2018 struct hci_conn *conn;
2019
2020 BT_DBG("%s status %d", hdev->name, ev->status);
2021
2022 hci_dev_lock(hdev);
2023
2024 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2025 if (conn) {
2026 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002027 if (ev->encrypt) {
2028 /* Encryption implies authentication */
2029 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002030 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002031 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002032 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002033 conn->link_mode &= ~HCI_LM_ENCRYPT;
2034 }
2035
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002036 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002037
Marcel Holtmannf8558552008-07-14 20:13:49 +02002038 if (conn->state == BT_CONFIG) {
2039 if (!ev->status)
2040 conn->state = BT_CONNECTED;
2041
2042 hci_proto_connect_cfm(conn, ev->status);
2043 hci_conn_put(conn);
2044 } else
2045 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002046 }
2047
2048 hci_dev_unlock(hdev);
2049}
2050
2051static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2052{
2053 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2054 struct hci_conn *conn;
2055
2056 BT_DBG("%s status %d", hdev->name, ev->status);
2057
2058 hci_dev_lock(hdev);
2059
2060 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2061 if (conn) {
2062 if (!ev->status)
2063 conn->link_mode |= HCI_LM_SECURE;
2064
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002065 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002066
2067 hci_key_change_cfm(conn, ev->status);
2068 }
2069
2070 hci_dev_unlock(hdev);
2071}
2072
2073static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2074{
2075 struct hci_ev_remote_features *ev = (void *) skb->data;
2076 struct hci_conn *conn;
2077
2078 BT_DBG("%s status %d", hdev->name, ev->status);
2079
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002080 hci_dev_lock(hdev);
2081
2082 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002083 if (!conn)
2084 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002085
Johan Hedbergccd556f2010-11-10 17:11:51 +02002086 if (!ev->status)
2087 memcpy(conn->features, ev->features, 8);
2088
2089 if (conn->state != BT_CONFIG)
2090 goto unlock;
2091
2092 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2093 struct hci_cp_read_remote_ext_features cp;
2094 cp.handle = ev->handle;
2095 cp.page = 0x01;
2096 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002097 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002098 goto unlock;
2099 }
2100
Johan Hedberg127178d2010-11-18 22:22:29 +02002101 if (!ev->status) {
2102 struct hci_cp_remote_name_req cp;
2103 memset(&cp, 0, sizeof(cp));
2104 bacpy(&cp.bdaddr, &conn->dst);
2105 cp.pscan_rep_mode = 0x02;
2106 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002107 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2108 mgmt_device_connected(hdev, &conn->dst, conn->type,
Johan Hedberg08c79b62012-02-23 22:31:51 +02002109 conn->dst_type, 0, NULL, 0,
Johan Hedbergb644ba32012-01-17 21:48:47 +02002110 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002111
Johan Hedberg127178d2010-11-18 22:22:29 +02002112 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002113 conn->state = BT_CONNECTED;
2114 hci_proto_connect_cfm(conn, ev->status);
2115 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002116 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002117
Johan Hedbergccd556f2010-11-10 17:11:51 +02002118unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002119 hci_dev_unlock(hdev);
2120}
2121
2122static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2123{
2124 BT_DBG("%s", hdev->name);
2125}
2126
2127static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2128{
2129 BT_DBG("%s", hdev->name);
2130}
2131
2132static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2133{
2134 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2135 __u16 opcode;
2136
2137 skb_pull(skb, sizeof(*ev));
2138
2139 opcode = __le16_to_cpu(ev->opcode);
2140
2141 switch (opcode) {
2142 case HCI_OP_INQUIRY_CANCEL:
2143 hci_cc_inquiry_cancel(hdev, skb);
2144 break;
2145
2146 case HCI_OP_EXIT_PERIODIC_INQ:
2147 hci_cc_exit_periodic_inq(hdev, skb);
2148 break;
2149
2150 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2151 hci_cc_remote_name_req_cancel(hdev, skb);
2152 break;
2153
2154 case HCI_OP_ROLE_DISCOVERY:
2155 hci_cc_role_discovery(hdev, skb);
2156 break;
2157
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002158 case HCI_OP_READ_LINK_POLICY:
2159 hci_cc_read_link_policy(hdev, skb);
2160 break;
2161
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002162 case HCI_OP_WRITE_LINK_POLICY:
2163 hci_cc_write_link_policy(hdev, skb);
2164 break;
2165
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002166 case HCI_OP_READ_DEF_LINK_POLICY:
2167 hci_cc_read_def_link_policy(hdev, skb);
2168 break;
2169
2170 case HCI_OP_WRITE_DEF_LINK_POLICY:
2171 hci_cc_write_def_link_policy(hdev, skb);
2172 break;
2173
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002174 case HCI_OP_RESET:
2175 hci_cc_reset(hdev, skb);
2176 break;
2177
2178 case HCI_OP_WRITE_LOCAL_NAME:
2179 hci_cc_write_local_name(hdev, skb);
2180 break;
2181
2182 case HCI_OP_READ_LOCAL_NAME:
2183 hci_cc_read_local_name(hdev, skb);
2184 break;
2185
2186 case HCI_OP_WRITE_AUTH_ENABLE:
2187 hci_cc_write_auth_enable(hdev, skb);
2188 break;
2189
2190 case HCI_OP_WRITE_ENCRYPT_MODE:
2191 hci_cc_write_encrypt_mode(hdev, skb);
2192 break;
2193
2194 case HCI_OP_WRITE_SCAN_ENABLE:
2195 hci_cc_write_scan_enable(hdev, skb);
2196 break;
2197
2198 case HCI_OP_READ_CLASS_OF_DEV:
2199 hci_cc_read_class_of_dev(hdev, skb);
2200 break;
2201
2202 case HCI_OP_WRITE_CLASS_OF_DEV:
2203 hci_cc_write_class_of_dev(hdev, skb);
2204 break;
2205
2206 case HCI_OP_READ_VOICE_SETTING:
2207 hci_cc_read_voice_setting(hdev, skb);
2208 break;
2209
2210 case HCI_OP_WRITE_VOICE_SETTING:
2211 hci_cc_write_voice_setting(hdev, skb);
2212 break;
2213
2214 case HCI_OP_HOST_BUFFER_SIZE:
2215 hci_cc_host_buffer_size(hdev, skb);
2216 break;
2217
Marcel Holtmann333140b2008-07-14 20:13:48 +02002218 case HCI_OP_WRITE_SSP_MODE:
2219 hci_cc_write_ssp_mode(hdev, skb);
2220 break;
2221
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002222 case HCI_OP_READ_LOCAL_VERSION:
2223 hci_cc_read_local_version(hdev, skb);
2224 break;
2225
2226 case HCI_OP_READ_LOCAL_COMMANDS:
2227 hci_cc_read_local_commands(hdev, skb);
2228 break;
2229
2230 case HCI_OP_READ_LOCAL_FEATURES:
2231 hci_cc_read_local_features(hdev, skb);
2232 break;
2233
Andre Guedes971e3a42011-06-30 19:20:52 -03002234 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2235 hci_cc_read_local_ext_features(hdev, skb);
2236 break;
2237
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002238 case HCI_OP_READ_BUFFER_SIZE:
2239 hci_cc_read_buffer_size(hdev, skb);
2240 break;
2241
2242 case HCI_OP_READ_BD_ADDR:
2243 hci_cc_read_bd_addr(hdev, skb);
2244 break;
2245
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002246 case HCI_OP_READ_DATA_BLOCK_SIZE:
2247 hci_cc_read_data_block_size(hdev, skb);
2248 break;
2249
Johan Hedberg23bb5762010-12-21 23:01:27 +02002250 case HCI_OP_WRITE_CA_TIMEOUT:
2251 hci_cc_write_ca_timeout(hdev, skb);
2252 break;
2253
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002254 case HCI_OP_READ_FLOW_CONTROL_MODE:
2255 hci_cc_read_flow_control_mode(hdev, skb);
2256 break;
2257
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002258 case HCI_OP_READ_LOCAL_AMP_INFO:
2259 hci_cc_read_local_amp_info(hdev, skb);
2260 break;
2261
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002262 case HCI_OP_DELETE_STORED_LINK_KEY:
2263 hci_cc_delete_stored_link_key(hdev, skb);
2264 break;
2265
Johan Hedbergd5859e22011-01-25 01:19:58 +02002266 case HCI_OP_SET_EVENT_MASK:
2267 hci_cc_set_event_mask(hdev, skb);
2268 break;
2269
2270 case HCI_OP_WRITE_INQUIRY_MODE:
2271 hci_cc_write_inquiry_mode(hdev, skb);
2272 break;
2273
2274 case HCI_OP_READ_INQ_RSP_TX_POWER:
2275 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2276 break;
2277
2278 case HCI_OP_SET_EVENT_FLT:
2279 hci_cc_set_event_flt(hdev, skb);
2280 break;
2281
Johan Hedberg980e1a52011-01-22 06:10:07 +02002282 case HCI_OP_PIN_CODE_REPLY:
2283 hci_cc_pin_code_reply(hdev, skb);
2284 break;
2285
2286 case HCI_OP_PIN_CODE_NEG_REPLY:
2287 hci_cc_pin_code_neg_reply(hdev, skb);
2288 break;
2289
Szymon Jancc35938b2011-03-22 13:12:21 +01002290 case HCI_OP_READ_LOCAL_OOB_DATA:
2291 hci_cc_read_local_oob_data_reply(hdev, skb);
2292 break;
2293
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002294 case HCI_OP_LE_READ_BUFFER_SIZE:
2295 hci_cc_le_read_buffer_size(hdev, skb);
2296 break;
2297
Johan Hedberga5c29682011-02-19 12:05:57 -03002298 case HCI_OP_USER_CONFIRM_REPLY:
2299 hci_cc_user_confirm_reply(hdev, skb);
2300 break;
2301
2302 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2303 hci_cc_user_confirm_neg_reply(hdev, skb);
2304 break;
2305
Brian Gix1143d452011-11-23 08:28:34 -08002306 case HCI_OP_USER_PASSKEY_REPLY:
2307 hci_cc_user_passkey_reply(hdev, skb);
2308 break;
2309
2310 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2311 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002312
2313 case HCI_OP_LE_SET_SCAN_PARAM:
2314 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002315 break;
2316
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002317 case HCI_OP_LE_SET_SCAN_ENABLE:
2318 hci_cc_le_set_scan_enable(hdev, skb);
2319 break;
2320
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002321 case HCI_OP_LE_LTK_REPLY:
2322 hci_cc_le_ltk_reply(hdev, skb);
2323 break;
2324
2325 case HCI_OP_LE_LTK_NEG_REPLY:
2326 hci_cc_le_ltk_neg_reply(hdev, skb);
2327 break;
2328
Andre Guedesf9b49302011-06-30 19:20:53 -03002329 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2330 hci_cc_write_le_host_supported(hdev, skb);
2331 break;
2332
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002333 default:
2334 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2335 break;
2336 }
2337
Ville Tervo6bd32322011-02-16 16:32:41 +02002338 if (ev->opcode != HCI_OP_NOP)
2339 del_timer(&hdev->cmd_timer);
2340
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002341 if (ev->ncmd) {
2342 atomic_set(&hdev->cmd_cnt, 1);
2343 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002344 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002345 }
2346}
2347
2348static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2349{
2350 struct hci_ev_cmd_status *ev = (void *) skb->data;
2351 __u16 opcode;
2352
2353 skb_pull(skb, sizeof(*ev));
2354
2355 opcode = __le16_to_cpu(ev->opcode);
2356
2357 switch (opcode) {
2358 case HCI_OP_INQUIRY:
2359 hci_cs_inquiry(hdev, ev->status);
2360 break;
2361
2362 case HCI_OP_CREATE_CONN:
2363 hci_cs_create_conn(hdev, ev->status);
2364 break;
2365
2366 case HCI_OP_ADD_SCO:
2367 hci_cs_add_sco(hdev, ev->status);
2368 break;
2369
Marcel Holtmannf8558552008-07-14 20:13:49 +02002370 case HCI_OP_AUTH_REQUESTED:
2371 hci_cs_auth_requested(hdev, ev->status);
2372 break;
2373
2374 case HCI_OP_SET_CONN_ENCRYPT:
2375 hci_cs_set_conn_encrypt(hdev, ev->status);
2376 break;
2377
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002378 case HCI_OP_REMOTE_NAME_REQ:
2379 hci_cs_remote_name_req(hdev, ev->status);
2380 break;
2381
Marcel Holtmann769be972008-07-14 20:13:49 +02002382 case HCI_OP_READ_REMOTE_FEATURES:
2383 hci_cs_read_remote_features(hdev, ev->status);
2384 break;
2385
2386 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2387 hci_cs_read_remote_ext_features(hdev, ev->status);
2388 break;
2389
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002390 case HCI_OP_SETUP_SYNC_CONN:
2391 hci_cs_setup_sync_conn(hdev, ev->status);
2392 break;
2393
2394 case HCI_OP_SNIFF_MODE:
2395 hci_cs_sniff_mode(hdev, ev->status);
2396 break;
2397
2398 case HCI_OP_EXIT_SNIFF_MODE:
2399 hci_cs_exit_sniff_mode(hdev, ev->status);
2400 break;
2401
Johan Hedberg8962ee72011-01-20 12:40:27 +02002402 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002403 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002404 break;
2405
Ville Tervofcd89c02011-02-10 22:38:47 -03002406 case HCI_OP_LE_CREATE_CONN:
2407 hci_cs_le_create_conn(hdev, ev->status);
2408 break;
2409
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002410 case HCI_OP_LE_START_ENC:
2411 hci_cs_le_start_enc(hdev, ev->status);
2412 break;
2413
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002414 default:
2415 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2416 break;
2417 }
2418
Ville Tervo6bd32322011-02-16 16:32:41 +02002419 if (ev->opcode != HCI_OP_NOP)
2420 del_timer(&hdev->cmd_timer);
2421
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002422 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002423 atomic_set(&hdev->cmd_cnt, 1);
2424 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002425 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002426 }
2427}
2428
2429static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2430{
2431 struct hci_ev_role_change *ev = (void *) skb->data;
2432 struct hci_conn *conn;
2433
2434 BT_DBG("%s status %d", hdev->name, ev->status);
2435
2436 hci_dev_lock(hdev);
2437
2438 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2439 if (conn) {
2440 if (!ev->status) {
2441 if (ev->role)
2442 conn->link_mode &= ~HCI_LM_MASTER;
2443 else
2444 conn->link_mode |= HCI_LM_MASTER;
2445 }
2446
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002447 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002448
2449 hci_role_switch_cfm(conn, ev->status, ev->role);
2450 }
2451
2452 hci_dev_unlock(hdev);
2453}
2454
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2456{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002457 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458 int i;
2459
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002460 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2461 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2462 return;
2463 }
2464
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002465 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2466 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002467 BT_DBG("%s bad parameters", hdev->name);
2468 return;
2469 }
2470
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002471 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2472
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002473 for (i = 0; i < ev->num_hndl; i++) {
2474 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002475 struct hci_conn *conn;
2476 __u16 handle, count;
2477
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002478 handle = __le16_to_cpu(info->handle);
2479 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002480
2481 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002482 if (!conn)
2483 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002484
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002485 conn->sent -= count;
2486
2487 switch (conn->type) {
2488 case ACL_LINK:
2489 hdev->acl_cnt += count;
2490 if (hdev->acl_cnt > hdev->acl_pkts)
2491 hdev->acl_cnt = hdev->acl_pkts;
2492 break;
2493
2494 case LE_LINK:
2495 if (hdev->le_pkts) {
2496 hdev->le_cnt += count;
2497 if (hdev->le_cnt > hdev->le_pkts)
2498 hdev->le_cnt = hdev->le_pkts;
2499 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002500 hdev->acl_cnt += count;
2501 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502 hdev->acl_cnt = hdev->acl_pkts;
2503 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002504 break;
2505
2506 case SCO_LINK:
2507 hdev->sco_cnt += count;
2508 if (hdev->sco_cnt > hdev->sco_pkts)
2509 hdev->sco_cnt = hdev->sco_pkts;
2510 break;
2511
2512 default:
2513 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2514 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515 }
2516 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002517
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002518 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002519}
2520
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002521static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2522 struct sk_buff *skb)
2523{
2524 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2525 int i;
2526
2527 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2528 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2529 return;
2530 }
2531
2532 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2533 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2534 BT_DBG("%s bad parameters", hdev->name);
2535 return;
2536 }
2537
2538 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2539 ev->num_hndl);
2540
2541 for (i = 0; i < ev->num_hndl; i++) {
2542 struct hci_comp_blocks_info *info = &ev->handles[i];
2543 struct hci_conn *conn;
2544 __u16 handle, block_count;
2545
2546 handle = __le16_to_cpu(info->handle);
2547 block_count = __le16_to_cpu(info->blocks);
2548
2549 conn = hci_conn_hash_lookup_handle(hdev, handle);
2550 if (!conn)
2551 continue;
2552
2553 conn->sent -= block_count;
2554
2555 switch (conn->type) {
2556 case ACL_LINK:
2557 hdev->block_cnt += block_count;
2558 if (hdev->block_cnt > hdev->num_blocks)
2559 hdev->block_cnt = hdev->num_blocks;
2560 break;
2561
2562 default:
2563 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2564 break;
2565 }
2566 }
2567
2568 queue_work(hdev->workqueue, &hdev->tx_work);
2569}
2570
Marcel Holtmann04837f62006-07-03 10:02:33 +02002571static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002572{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002573 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002574 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575
2576 BT_DBG("%s status %d", hdev->name, ev->status);
2577
2578 hci_dev_lock(hdev);
2579
Marcel Holtmann04837f62006-07-03 10:02:33 +02002580 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2581 if (conn) {
2582 conn->mode = ev->mode;
2583 conn->interval = __le16_to_cpu(ev->interval);
2584
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002585 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002586 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002587 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002588 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002589 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002590 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002591
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002592 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002593 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002594 }
2595
2596 hci_dev_unlock(hdev);
2597}
2598
Linus Torvalds1da177e2005-04-16 15:20:36 -07002599static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2600{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002601 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2602 struct hci_conn *conn;
2603
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002604 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002605
2606 hci_dev_lock(hdev);
2607
2608 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002609 if (!conn)
2610 goto unlock;
2611
2612 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002613 hci_conn_hold(conn);
2614 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2615 hci_conn_put(conn);
2616 }
2617
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002618 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002619 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2620 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002621 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002622 u8 secure;
2623
2624 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2625 secure = 1;
2626 else
2627 secure = 0;
2628
Johan Hedberg744cf192011-11-08 20:40:14 +02002629 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002630 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002631
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002632unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002633 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634}
2635
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2637{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002638 struct hci_ev_link_key_req *ev = (void *) skb->data;
2639 struct hci_cp_link_key_reply cp;
2640 struct hci_conn *conn;
2641 struct link_key *key;
2642
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002643 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002644
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002645 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002646 return;
2647
2648 hci_dev_lock(hdev);
2649
2650 key = hci_find_link_key(hdev, &ev->bdaddr);
2651 if (!key) {
2652 BT_DBG("%s link key not found for %s", hdev->name,
2653 batostr(&ev->bdaddr));
2654 goto not_found;
2655 }
2656
2657 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2658 batostr(&ev->bdaddr));
2659
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002660 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002661 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002662 BT_DBG("%s ignoring debug key", hdev->name);
2663 goto not_found;
2664 }
2665
2666 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002667 if (conn) {
2668 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2669 conn->auth_type != 0xff &&
2670 (conn->auth_type & 0x01)) {
2671 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2672 goto not_found;
2673 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002674
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002675 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2676 conn->pending_sec_level == BT_SECURITY_HIGH) {
2677 BT_DBG("%s ignoring key unauthenticated for high \
2678 security", hdev->name);
2679 goto not_found;
2680 }
2681
2682 conn->key_type = key->type;
2683 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002684 }
2685
2686 bacpy(&cp.bdaddr, &ev->bdaddr);
2687 memcpy(cp.link_key, key->val, 16);
2688
2689 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2690
2691 hci_dev_unlock(hdev);
2692
2693 return;
2694
2695not_found:
2696 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2697 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002698}
2699
Linus Torvalds1da177e2005-04-16 15:20:36 -07002700static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2701{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002702 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2703 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002704 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002705
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002706 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002707
2708 hci_dev_lock(hdev);
2709
2710 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2711 if (conn) {
2712 hci_conn_hold(conn);
2713 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002714 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002715
2716 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2717 conn->key_type = ev->key_type;
2718
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002719 hci_conn_put(conn);
2720 }
2721
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002722 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002723 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002724 ev->key_type, pin_len);
2725
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002726 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727}
2728
Marcel Holtmann04837f62006-07-03 10:02:33 +02002729static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2730{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002731 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002732 struct hci_conn *conn;
2733
2734 BT_DBG("%s status %d", hdev->name, ev->status);
2735
2736 hci_dev_lock(hdev);
2737
2738 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002739 if (conn && !ev->status) {
2740 struct inquiry_entry *ie;
2741
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002742 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2743 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744 ie->data.clock_offset = ev->clock_offset;
2745 ie->timestamp = jiffies;
2746 }
2747 }
2748
2749 hci_dev_unlock(hdev);
2750}
2751
Marcel Holtmanna8746412008-07-14 20:13:46 +02002752static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2753{
2754 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2755 struct hci_conn *conn;
2756
2757 BT_DBG("%s status %d", hdev->name, ev->status);
2758
2759 hci_dev_lock(hdev);
2760
2761 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2762 if (conn && !ev->status)
2763 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2764
2765 hci_dev_unlock(hdev);
2766}
2767
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002768static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2769{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002770 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002771 struct inquiry_entry *ie;
2772
2773 BT_DBG("%s", hdev->name);
2774
2775 hci_dev_lock(hdev);
2776
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002777 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2778 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002779 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2780 ie->timestamp = jiffies;
2781 }
2782
2783 hci_dev_unlock(hdev);
2784}
2785
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002786static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2787{
2788 struct inquiry_data data;
2789 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002790 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002791
2792 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2793
2794 if (!num_rsp)
2795 return;
2796
2797 hci_dev_lock(hdev);
2798
2799 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002800 struct inquiry_info_with_rssi_and_pscan_mode *info;
2801 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002802
Johan Hedberge17acd42011-03-30 23:57:16 +03002803 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002804 bacpy(&data.bdaddr, &info->bdaddr);
2805 data.pscan_rep_mode = info->pscan_rep_mode;
2806 data.pscan_period_mode = info->pscan_period_mode;
2807 data.pscan_mode = info->pscan_mode;
2808 memcpy(data.dev_class, info->dev_class, 3);
2809 data.clock_offset = info->clock_offset;
2810 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002811 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002812
2813 name_known = hci_inquiry_cache_update(hdev, &data,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002814 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002815 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002816 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002817 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002818 }
2819 } else {
2820 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2821
Johan Hedberge17acd42011-03-30 23:57:16 +03002822 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002823 bacpy(&data.bdaddr, &info->bdaddr);
2824 data.pscan_rep_mode = info->pscan_rep_mode;
2825 data.pscan_period_mode = info->pscan_period_mode;
2826 data.pscan_mode = 0x00;
2827 memcpy(data.dev_class, info->dev_class, 3);
2828 data.clock_offset = info->clock_offset;
2829 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002830 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002831 name_known = hci_inquiry_cache_update(hdev, &data,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002832 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002833 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002834 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002835 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002836 }
2837 }
2838
2839 hci_dev_unlock(hdev);
2840}
2841
2842static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2843{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002844 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2845 struct hci_conn *conn;
2846
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002847 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002848
Marcel Holtmann41a96212008-07-14 20:13:48 +02002849 hci_dev_lock(hdev);
2850
2851 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002852 if (!conn)
2853 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002854
Johan Hedbergccd556f2010-11-10 17:11:51 +02002855 if (!ev->status && ev->page == 0x01) {
2856 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002857
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002858 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2859 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002860 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002861
Johan Hedberg58a681e2012-01-16 06:47:28 +02002862 if (ev->features[0] & 0x01)
2863 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002864 }
2865
Johan Hedbergccd556f2010-11-10 17:11:51 +02002866 if (conn->state != BT_CONFIG)
2867 goto unlock;
2868
Johan Hedberg127178d2010-11-18 22:22:29 +02002869 if (!ev->status) {
2870 struct hci_cp_remote_name_req cp;
2871 memset(&cp, 0, sizeof(cp));
2872 bacpy(&cp.bdaddr, &conn->dst);
2873 cp.pscan_rep_mode = 0x02;
2874 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002875 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2876 mgmt_device_connected(hdev, &conn->dst, conn->type,
Johan Hedberg08c79b62012-02-23 22:31:51 +02002877 conn->dst_type, 0, NULL, 0,
Johan Hedbergb644ba32012-01-17 21:48:47 +02002878 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002879
Johan Hedberg127178d2010-11-18 22:22:29 +02002880 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002881 conn->state = BT_CONNECTED;
2882 hci_proto_connect_cfm(conn, ev->status);
2883 hci_conn_put(conn);
2884 }
2885
2886unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002887 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002888}
2889
2890static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2891{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002892 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2893 struct hci_conn *conn;
2894
2895 BT_DBG("%s status %d", hdev->name, ev->status);
2896
2897 hci_dev_lock(hdev);
2898
2899 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002900 if (!conn) {
2901 if (ev->link_type == ESCO_LINK)
2902 goto unlock;
2903
2904 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2905 if (!conn)
2906 goto unlock;
2907
2908 conn->type = SCO_LINK;
2909 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002910
Marcel Holtmann732547f2009-04-19 19:14:14 +02002911 switch (ev->status) {
2912 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002913 conn->handle = __le16_to_cpu(ev->handle);
2914 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002915
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002916 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002917 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002918 break;
2919
Stephen Coe705e5712010-02-16 11:29:44 -05002920 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002921 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002922 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002923 case 0x1f: /* Unspecified error */
2924 if (conn->out && conn->attempt < 2) {
2925 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2926 (hdev->esco_type & EDR_ESCO_MASK);
2927 hci_setup_sync(conn, conn->link->handle);
2928 goto unlock;
2929 }
2930 /* fall through */
2931
2932 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002933 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002934 break;
2935 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002936
2937 hci_proto_connect_cfm(conn, ev->status);
2938 if (ev->status)
2939 hci_conn_del(conn);
2940
2941unlock:
2942 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002943}
2944
2945static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2946{
2947 BT_DBG("%s", hdev->name);
2948}
2949
Marcel Holtmann04837f62006-07-03 10:02:33 +02002950static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2951{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002952 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002953
2954 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002955}
2956
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002957static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2958{
2959 struct inquiry_data data;
2960 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2961 int num_rsp = *((__u8 *) skb->data);
2962
2963 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2964
2965 if (!num_rsp)
2966 return;
2967
2968 hci_dev_lock(hdev);
2969
Johan Hedberge17acd42011-03-30 23:57:16 +03002970 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002971 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002972
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002973 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002974 data.pscan_rep_mode = info->pscan_rep_mode;
2975 data.pscan_period_mode = info->pscan_period_mode;
2976 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002977 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002978 data.clock_offset = info->clock_offset;
2979 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002980 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002981
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002982 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002983 name_known = eir_has_data_type(info->data,
2984 sizeof(info->data),
2985 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002986 else
2987 name_known = true;
2988
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002989 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
2990 &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002991 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002992 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002993 !name_known, ssp, info->data,
Andre Guedes7d262f82012-01-10 18:20:49 -03002994 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002995 }
2996
2997 hci_dev_unlock(hdev);
2998}
2999
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003000static inline u8 hci_get_auth_req(struct hci_conn *conn)
3001{
3002 /* If remote requests dedicated bonding follow that lead */
3003 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3004 /* If both remote and local IO capabilities allow MITM
3005 * protection then require it, otherwise don't */
3006 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3007 return 0x02;
3008 else
3009 return 0x03;
3010 }
3011
3012 /* If remote requests no-bonding follow that lead */
3013 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003014 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003015
3016 return conn->auth_type;
3017}
3018
Marcel Holtmann04936842008-07-14 20:13:48 +02003019static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3020{
3021 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3022 struct hci_conn *conn;
3023
3024 BT_DBG("%s", hdev->name);
3025
3026 hci_dev_lock(hdev);
3027
3028 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003029 if (!conn)
3030 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003031
Johan Hedberg03b555e2011-01-04 15:40:05 +02003032 hci_conn_hold(conn);
3033
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003034 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003035 goto unlock;
3036
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003037 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003038 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003039 struct hci_cp_io_capability_reply cp;
3040
3041 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303042 /* Change the IO capability from KeyboardDisplay
3043 * to DisplayYesNo as it is not supported by BT spec. */
3044 cp.capability = (conn->io_capability == 0x04) ?
3045 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003046 conn->auth_type = hci_get_auth_req(conn);
3047 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003048
Johan Hedberg58a681e2012-01-16 06:47:28 +02003049 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003050 hci_find_remote_oob_data(hdev, &conn->dst))
3051 cp.oob_data = 0x01;
3052 else
3053 cp.oob_data = 0x00;
3054
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003055 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3056 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003057 } else {
3058 struct hci_cp_io_capability_neg_reply cp;
3059
3060 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003061 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003062
3063 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3064 sizeof(cp), &cp);
3065 }
3066
3067unlock:
3068 hci_dev_unlock(hdev);
3069}
3070
3071static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3072{
3073 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3074 struct hci_conn *conn;
3075
3076 BT_DBG("%s", hdev->name);
3077
3078 hci_dev_lock(hdev);
3079
3080 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3081 if (!conn)
3082 goto unlock;
3083
Johan Hedberg03b555e2011-01-04 15:40:05 +02003084 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003085 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003086 if (ev->oob_data)
3087 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003088
3089unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003090 hci_dev_unlock(hdev);
3091}
3092
Johan Hedberga5c29682011-02-19 12:05:57 -03003093static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3094 struct sk_buff *skb)
3095{
3096 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003097 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003098 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003099
3100 BT_DBG("%s", hdev->name);
3101
3102 hci_dev_lock(hdev);
3103
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003104 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003105 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003106
Johan Hedberg7a828902011-04-28 11:28:53 -07003107 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3108 if (!conn)
3109 goto unlock;
3110
3111 loc_mitm = (conn->auth_type & 0x01);
3112 rem_mitm = (conn->remote_auth & 0x01);
3113
3114 /* If we require MITM but the remote device can't provide that
3115 * (it has NoInputNoOutput) then reject the confirmation
3116 * request. The only exception is when we're dedicated bonding
3117 * initiators (connect_cfm_cb set) since then we always have the MITM
3118 * bit set. */
3119 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3120 BT_DBG("Rejecting request: remote device can't provide MITM");
3121 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3122 sizeof(ev->bdaddr), &ev->bdaddr);
3123 goto unlock;
3124 }
3125
3126 /* If no side requires MITM protection; auto-accept */
3127 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3128 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003129
3130 /* If we're not the initiators request authorization to
3131 * proceed from user space (mgmt_user_confirm with
3132 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003133 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003134 BT_DBG("Confirming auto-accept as acceptor");
3135 confirm_hint = 1;
3136 goto confirm;
3137 }
3138
Johan Hedberg9f616562011-04-28 11:28:54 -07003139 BT_DBG("Auto-accept of user confirmation with %ums delay",
3140 hdev->auto_accept_delay);
3141
3142 if (hdev->auto_accept_delay > 0) {
3143 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3144 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3145 goto unlock;
3146 }
3147
Johan Hedberg7a828902011-04-28 11:28:53 -07003148 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3149 sizeof(ev->bdaddr), &ev->bdaddr);
3150 goto unlock;
3151 }
3152
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003153confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003154 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003155 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003156
3157unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003158 hci_dev_unlock(hdev);
3159}
3160
Brian Gix1143d452011-11-23 08:28:34 -08003161static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3162 struct sk_buff *skb)
3163{
3164 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3165
3166 BT_DBG("%s", hdev->name);
3167
3168 hci_dev_lock(hdev);
3169
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003170 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003171 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003172
3173 hci_dev_unlock(hdev);
3174}
3175
Marcel Holtmann04936842008-07-14 20:13:48 +02003176static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3177{
3178 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3179 struct hci_conn *conn;
3180
3181 BT_DBG("%s", hdev->name);
3182
3183 hci_dev_lock(hdev);
3184
3185 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003186 if (!conn)
3187 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003188
Johan Hedberg2a611692011-02-19 12:06:00 -03003189 /* To avoid duplicate auth_failed events to user space we check
3190 * the HCI_CONN_AUTH_PEND flag which will be set if we
3191 * initiated the authentication. A traditional auth_complete
3192 * event gets always produced as initiator and is also mapped to
3193 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003194 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003195 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3196 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003197
3198 hci_conn_put(conn);
3199
3200unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003201 hci_dev_unlock(hdev);
3202}
3203
Marcel Holtmann41a96212008-07-14 20:13:48 +02003204static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3205{
3206 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3207 struct inquiry_entry *ie;
3208
3209 BT_DBG("%s", hdev->name);
3210
3211 hci_dev_lock(hdev);
3212
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003213 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3214 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003215 ie->data.ssp_mode = (ev->features[0] & 0x01);
3216
3217 hci_dev_unlock(hdev);
3218}
3219
Szymon Janc2763eda2011-03-22 13:12:22 +01003220static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3221 struct sk_buff *skb)
3222{
3223 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3224 struct oob_data *data;
3225
3226 BT_DBG("%s", hdev->name);
3227
3228 hci_dev_lock(hdev);
3229
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003230 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003231 goto unlock;
3232
Szymon Janc2763eda2011-03-22 13:12:22 +01003233 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3234 if (data) {
3235 struct hci_cp_remote_oob_data_reply cp;
3236
3237 bacpy(&cp.bdaddr, &ev->bdaddr);
3238 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3239 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3240
3241 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3242 &cp);
3243 } else {
3244 struct hci_cp_remote_oob_data_neg_reply cp;
3245
3246 bacpy(&cp.bdaddr, &ev->bdaddr);
3247 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3248 &cp);
3249 }
3250
Szymon Jance1ba1f12011-04-06 13:01:59 +02003251unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003252 hci_dev_unlock(hdev);
3253}
3254
Ville Tervofcd89c02011-02-10 22:38:47 -03003255static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3256{
3257 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3258 struct hci_conn *conn;
3259
3260 BT_DBG("%s status %d", hdev->name, ev->status);
3261
3262 hci_dev_lock(hdev);
3263
3264 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003265 if (!conn) {
3266 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3267 if (!conn) {
3268 BT_ERR("No memory for new connection");
3269 hci_dev_unlock(hdev);
3270 return;
3271 }
Andre Guedes29b79882011-05-31 14:20:54 -03003272
3273 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003274 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003275
3276 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003277 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3278 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003279 hci_proto_connect_cfm(conn, ev->status);
3280 conn->state = BT_CLOSED;
3281 hci_conn_del(conn);
3282 goto unlock;
3283 }
3284
Johan Hedbergb644ba32012-01-17 21:48:47 +02003285 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3286 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Johan Hedberg08c79b62012-02-23 22:31:51 +02003287 conn->dst_type, 0, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003288
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003289 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003290 conn->handle = __le16_to_cpu(ev->handle);
3291 conn->state = BT_CONNECTED;
3292
3293 hci_conn_hold_device(conn);
3294 hci_conn_add_sysfs(conn);
3295
3296 hci_proto_connect_cfm(conn, ev->status);
3297
3298unlock:
3299 hci_dev_unlock(hdev);
3300}
3301
Andre Guedes9aa04c92011-05-26 16:23:51 -03003302static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3303 struct sk_buff *skb)
3304{
Andre Guedese95beb42011-09-26 20:48:35 -03003305 u8 num_reports = skb->data[0];
3306 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003307 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003308
3309 hci_dev_lock(hdev);
3310
Andre Guedese95beb42011-09-26 20:48:35 -03003311 while (num_reports--) {
3312 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003313
Andre Guedes9aa04c92011-05-26 16:23:51 -03003314 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003315
Andre Guedes3c9e9192012-01-10 18:20:50 -03003316 rssi = ev->data[ev->length];
3317 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003318 NULL, rssi, 0, 1, ev->data,
3319 ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003320
Andre Guedese95beb42011-09-26 20:48:35 -03003321 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003322 }
3323
3324 hci_dev_unlock(hdev);
3325}
3326
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003327static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3328 struct sk_buff *skb)
3329{
3330 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3331 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003332 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003333 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003334 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003335
3336 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3337
3338 hci_dev_lock(hdev);
3339
3340 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003341 if (conn == NULL)
3342 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003343
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003344 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3345 if (ltk == NULL)
3346 goto not_found;
3347
3348 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003349 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003350
3351 if (ltk->authenticated)
3352 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003353
3354 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3355
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003356 if (ltk->type & HCI_SMP_STK) {
3357 list_del(&ltk->list);
3358 kfree(ltk);
3359 }
3360
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003361 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003362
3363 return;
3364
3365not_found:
3366 neg.handle = ev->handle;
3367 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3368 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003369}
3370
Ville Tervofcd89c02011-02-10 22:38:47 -03003371static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3372{
3373 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3374
3375 skb_pull(skb, sizeof(*le_ev));
3376
3377 switch (le_ev->subevent) {
3378 case HCI_EV_LE_CONN_COMPLETE:
3379 hci_le_conn_complete_evt(hdev, skb);
3380 break;
3381
Andre Guedes9aa04c92011-05-26 16:23:51 -03003382 case HCI_EV_LE_ADVERTISING_REPORT:
3383 hci_le_adv_report_evt(hdev, skb);
3384 break;
3385
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003386 case HCI_EV_LE_LTK_REQ:
3387 hci_le_ltk_request_evt(hdev, skb);
3388 break;
3389
Ville Tervofcd89c02011-02-10 22:38:47 -03003390 default:
3391 break;
3392 }
3393}
3394
Linus Torvalds1da177e2005-04-16 15:20:36 -07003395void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3396{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003397 struct hci_event_hdr *hdr = (void *) skb->data;
3398 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003399
3400 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3401
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003402 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403 case HCI_EV_INQUIRY_COMPLETE:
3404 hci_inquiry_complete_evt(hdev, skb);
3405 break;
3406
3407 case HCI_EV_INQUIRY_RESULT:
3408 hci_inquiry_result_evt(hdev, skb);
3409 break;
3410
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003411 case HCI_EV_CONN_COMPLETE:
3412 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003413 break;
3414
Linus Torvalds1da177e2005-04-16 15:20:36 -07003415 case HCI_EV_CONN_REQUEST:
3416 hci_conn_request_evt(hdev, skb);
3417 break;
3418
Linus Torvalds1da177e2005-04-16 15:20:36 -07003419 case HCI_EV_DISCONN_COMPLETE:
3420 hci_disconn_complete_evt(hdev, skb);
3421 break;
3422
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423 case HCI_EV_AUTH_COMPLETE:
3424 hci_auth_complete_evt(hdev, skb);
3425 break;
3426
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003427 case HCI_EV_REMOTE_NAME:
3428 hci_remote_name_evt(hdev, skb);
3429 break;
3430
Linus Torvalds1da177e2005-04-16 15:20:36 -07003431 case HCI_EV_ENCRYPT_CHANGE:
3432 hci_encrypt_change_evt(hdev, skb);
3433 break;
3434
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003435 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3436 hci_change_link_key_complete_evt(hdev, skb);
3437 break;
3438
3439 case HCI_EV_REMOTE_FEATURES:
3440 hci_remote_features_evt(hdev, skb);
3441 break;
3442
3443 case HCI_EV_REMOTE_VERSION:
3444 hci_remote_version_evt(hdev, skb);
3445 break;
3446
3447 case HCI_EV_QOS_SETUP_COMPLETE:
3448 hci_qos_setup_complete_evt(hdev, skb);
3449 break;
3450
3451 case HCI_EV_CMD_COMPLETE:
3452 hci_cmd_complete_evt(hdev, skb);
3453 break;
3454
3455 case HCI_EV_CMD_STATUS:
3456 hci_cmd_status_evt(hdev, skb);
3457 break;
3458
3459 case HCI_EV_ROLE_CHANGE:
3460 hci_role_change_evt(hdev, skb);
3461 break;
3462
3463 case HCI_EV_NUM_COMP_PKTS:
3464 hci_num_comp_pkts_evt(hdev, skb);
3465 break;
3466
3467 case HCI_EV_MODE_CHANGE:
3468 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003469 break;
3470
3471 case HCI_EV_PIN_CODE_REQ:
3472 hci_pin_code_request_evt(hdev, skb);
3473 break;
3474
3475 case HCI_EV_LINK_KEY_REQ:
3476 hci_link_key_request_evt(hdev, skb);
3477 break;
3478
3479 case HCI_EV_LINK_KEY_NOTIFY:
3480 hci_link_key_notify_evt(hdev, skb);
3481 break;
3482
3483 case HCI_EV_CLOCK_OFFSET:
3484 hci_clock_offset_evt(hdev, skb);
3485 break;
3486
Marcel Holtmanna8746412008-07-14 20:13:46 +02003487 case HCI_EV_PKT_TYPE_CHANGE:
3488 hci_pkt_type_change_evt(hdev, skb);
3489 break;
3490
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003491 case HCI_EV_PSCAN_REP_MODE:
3492 hci_pscan_rep_mode_evt(hdev, skb);
3493 break;
3494
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003495 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3496 hci_inquiry_result_with_rssi_evt(hdev, skb);
3497 break;
3498
3499 case HCI_EV_REMOTE_EXT_FEATURES:
3500 hci_remote_ext_features_evt(hdev, skb);
3501 break;
3502
3503 case HCI_EV_SYNC_CONN_COMPLETE:
3504 hci_sync_conn_complete_evt(hdev, skb);
3505 break;
3506
3507 case HCI_EV_SYNC_CONN_CHANGED:
3508 hci_sync_conn_changed_evt(hdev, skb);
3509 break;
3510
Marcel Holtmann04837f62006-07-03 10:02:33 +02003511 case HCI_EV_SNIFF_SUBRATE:
3512 hci_sniff_subrate_evt(hdev, skb);
3513 break;
3514
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003515 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3516 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003517 break;
3518
Marcel Holtmann04936842008-07-14 20:13:48 +02003519 case HCI_EV_IO_CAPA_REQUEST:
3520 hci_io_capa_request_evt(hdev, skb);
3521 break;
3522
Johan Hedberg03b555e2011-01-04 15:40:05 +02003523 case HCI_EV_IO_CAPA_REPLY:
3524 hci_io_capa_reply_evt(hdev, skb);
3525 break;
3526
Johan Hedberga5c29682011-02-19 12:05:57 -03003527 case HCI_EV_USER_CONFIRM_REQUEST:
3528 hci_user_confirm_request_evt(hdev, skb);
3529 break;
3530
Brian Gix1143d452011-11-23 08:28:34 -08003531 case HCI_EV_USER_PASSKEY_REQUEST:
3532 hci_user_passkey_request_evt(hdev, skb);
3533 break;
3534
Marcel Holtmann04936842008-07-14 20:13:48 +02003535 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3536 hci_simple_pair_complete_evt(hdev, skb);
3537 break;
3538
Marcel Holtmann41a96212008-07-14 20:13:48 +02003539 case HCI_EV_REMOTE_HOST_FEATURES:
3540 hci_remote_host_features_evt(hdev, skb);
3541 break;
3542
Ville Tervofcd89c02011-02-10 22:38:47 -03003543 case HCI_EV_LE_META:
3544 hci_le_meta_evt(hdev, skb);
3545 break;
3546
Szymon Janc2763eda2011-03-22 13:12:22 +01003547 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3548 hci_remote_oob_data_request_evt(hdev, skb);
3549 break;
3550
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003551 case HCI_EV_NUM_COMP_BLOCKS:
3552 hci_num_comp_blocks_evt(hdev, skb);
3553 break;
3554
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003555 default:
3556 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003557 break;
3558 }
3559
3560 kfree_skb(skb);
3561 hdev->stat.evt_rx++;
3562}