blob: aee9556e10390bf389e00b1bc72b3215eab00e72 [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
545static void hci_setup(struct hci_dev *hdev)
546{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200547 if (hdev->dev_type != HCI_BREDR)
548 return;
549
Johan Hedbergd5859e22011-01-25 01:19:58 +0200550 hci_setup_event_mask(hdev);
551
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200552 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200553 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
554
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200555 if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
556 test_bit(HCI_MGMT, &hdev->dev_flags)) {
557 struct hci_cp_write_local_name cp;
558
559 memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
560 hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp);
561 }
562
Johan Hedberg54d04db2012-02-22 15:47:48 +0200563 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
564 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
565 u8 mode = 0x01;
566 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
567 sizeof(mode), &mode);
568 } else {
569 struct hci_cp_write_eir cp;
570
571 memset(hdev->eir, 0, sizeof(hdev->eir));
572 memset(&cp, 0, sizeof(cp));
573
574 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
575 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200576 }
577
578 if (hdev->features[3] & LMP_RSSI_INQ)
579 hci_setup_inquiry_mode(hdev);
580
581 if (hdev->features[7] & LMP_INQ_TX_PWR)
582 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300583
584 if (hdev->features[7] & LMP_EXTFEATURES) {
585 struct hci_cp_read_local_ext_features cp;
586
587 cp.page = 0x01;
588 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
589 sizeof(cp), &cp);
590 }
Andre Guedese6100a22011-06-30 19:20:54 -0300591
Johan Hedberg47990ea2012-02-22 11:58:37 +0200592 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
593 u8 enable = 1;
594 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE,
595 sizeof(enable), &enable);
596 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200597}
598
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200599static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
600{
601 struct hci_rp_read_local_version *rp = (void *) skb->data;
602
603 BT_DBG("%s status 0x%x", hdev->name, rp->status);
604
605 if (rp->status)
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200606 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200607
608 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200609 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200610 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200611 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200612 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200613
614 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
615 hdev->manufacturer,
616 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200617
618 if (test_bit(HCI_INIT, &hdev->flags))
619 hci_setup(hdev);
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200620
621done:
622 hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200623}
624
625static void hci_setup_link_policy(struct hci_dev *hdev)
626{
627 u16 link_policy = 0;
628
629 if (hdev->features[0] & LMP_RSWITCH)
630 link_policy |= HCI_LP_RSWITCH;
631 if (hdev->features[0] & LMP_HOLD)
632 link_policy |= HCI_LP_HOLD;
633 if (hdev->features[0] & LMP_SNIFF)
634 link_policy |= HCI_LP_SNIFF;
635 if (hdev->features[1] & LMP_PARK)
636 link_policy |= HCI_LP_PARK;
637
638 link_policy = cpu_to_le16(link_policy);
639 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
640 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200641}
642
643static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
644{
645 struct hci_rp_read_local_commands *rp = (void *) skb->data;
646
647 BT_DBG("%s status 0x%x", hdev->name, rp->status);
648
649 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200650 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200651
652 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200653
654 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
655 hci_setup_link_policy(hdev);
656
657done:
658 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200659}
660
661static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
662{
663 struct hci_rp_read_local_features *rp = (void *) skb->data;
664
665 BT_DBG("%s status 0x%x", hdev->name, rp->status);
666
667 if (rp->status)
668 return;
669
670 memcpy(hdev->features, rp->features, 8);
671
672 /* Adjust default settings according to features
673 * supported by device. */
674
675 if (hdev->features[0] & LMP_3SLOT)
676 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
677
678 if (hdev->features[0] & LMP_5SLOT)
679 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
680
681 if (hdev->features[1] & LMP_HV2) {
682 hdev->pkt_type |= (HCI_HV2);
683 hdev->esco_type |= (ESCO_HV2);
684 }
685
686 if (hdev->features[1] & LMP_HV3) {
687 hdev->pkt_type |= (HCI_HV3);
688 hdev->esco_type |= (ESCO_HV3);
689 }
690
691 if (hdev->features[3] & LMP_ESCO)
692 hdev->esco_type |= (ESCO_EV3);
693
694 if (hdev->features[4] & LMP_EV4)
695 hdev->esco_type |= (ESCO_EV4);
696
697 if (hdev->features[4] & LMP_EV5)
698 hdev->esco_type |= (ESCO_EV5);
699
Marcel Holtmannefc76882009-02-06 09:13:37 +0100700 if (hdev->features[5] & LMP_EDR_ESCO_2M)
701 hdev->esco_type |= (ESCO_2EV3);
702
703 if (hdev->features[5] & LMP_EDR_ESCO_3M)
704 hdev->esco_type |= (ESCO_3EV3);
705
706 if (hdev->features[5] & LMP_EDR_3S_ESCO)
707 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
708
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200709 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
710 hdev->features[0], hdev->features[1],
711 hdev->features[2], hdev->features[3],
712 hdev->features[4], hdev->features[5],
713 hdev->features[6], hdev->features[7]);
714}
715
Johan Hedberg8f984df2012-02-28 01:07:22 +0200716static void hci_set_le_support(struct hci_dev *hdev)
717{
718 struct hci_cp_write_le_host_supported cp;
719
720 memset(&cp, 0, sizeof(cp));
721
722 if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
723 cp.le = 1;
724 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
725 }
726
727 if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE))
728 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED,
729 sizeof(cp), &cp);
730}
731
Andre Guedes971e3a42011-06-30 19:20:52 -0300732static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
733 struct sk_buff *skb)
734{
735 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
736
737 BT_DBG("%s status 0x%x", hdev->name, rp->status);
738
739 if (rp->status)
Johan Hedberg8f984df2012-02-28 01:07:22 +0200740 goto done;
Andre Guedes971e3a42011-06-30 19:20:52 -0300741
Andre Guedesb5b32b62011-12-30 10:34:04 -0300742 switch (rp->page) {
743 case 0:
744 memcpy(hdev->features, rp->features, 8);
745 break;
746 case 1:
747 memcpy(hdev->host_features, rp->features, 8);
748 break;
749 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300750
Johan Hedberg8f984df2012-02-28 01:07:22 +0200751 if (test_bit(HCI_INIT, &hdev->flags) && hdev->features[4] & LMP_LE)
752 hci_set_le_support(hdev);
753
754done:
Andre Guedes971e3a42011-06-30 19:20:52 -0300755 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
756}
757
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200758static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
759 struct sk_buff *skb)
760{
761 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
762
763 BT_DBG("%s status 0x%x", hdev->name, rp->status);
764
765 if (rp->status)
766 return;
767
768 hdev->flow_ctl_mode = rp->mode;
769
770 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
771}
772
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200773static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
774{
775 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
776
777 BT_DBG("%s status 0x%x", hdev->name, rp->status);
778
779 if (rp->status)
780 return;
781
782 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
783 hdev->sco_mtu = rp->sco_mtu;
784 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
785 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
786
787 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
788 hdev->sco_mtu = 64;
789 hdev->sco_pkts = 8;
790 }
791
792 hdev->acl_cnt = hdev->acl_pkts;
793 hdev->sco_cnt = hdev->sco_pkts;
794
795 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
796 hdev->acl_mtu, hdev->acl_pkts,
797 hdev->sco_mtu, hdev->sco_pkts);
798}
799
800static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
801{
802 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
803
804 BT_DBG("%s status 0x%x", hdev->name, rp->status);
805
806 if (!rp->status)
807 bacpy(&hdev->bdaddr, &rp->bdaddr);
808
Johan Hedberg23bb5762010-12-21 23:01:27 +0200809 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
810}
811
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200812static void hci_cc_read_data_block_size(struct hci_dev *hdev,
813 struct sk_buff *skb)
814{
815 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
816
817 BT_DBG("%s status 0x%x", hdev->name, rp->status);
818
819 if (rp->status)
820 return;
821
822 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
823 hdev->block_len = __le16_to_cpu(rp->block_len);
824 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
825
826 hdev->block_cnt = hdev->num_blocks;
827
828 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
829 hdev->block_cnt, hdev->block_len);
830
831 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
832}
833
Johan Hedberg23bb5762010-12-21 23:01:27 +0200834static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
835{
836 __u8 status = *((__u8 *) skb->data);
837
838 BT_DBG("%s status 0x%x", hdev->name, status);
839
840 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200841}
842
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300843static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
844 struct sk_buff *skb)
845{
846 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
847
848 BT_DBG("%s status 0x%x", hdev->name, rp->status);
849
850 if (rp->status)
851 return;
852
853 hdev->amp_status = rp->amp_status;
854 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
855 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
856 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
857 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
858 hdev->amp_type = rp->amp_type;
859 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
860 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
861 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
862 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
863
864 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
865}
866
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200867static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
868 struct sk_buff *skb)
869{
870 __u8 status = *((__u8 *) skb->data);
871
872 BT_DBG("%s status 0x%x", hdev->name, status);
873
874 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
875}
876
Johan Hedbergd5859e22011-01-25 01:19:58 +0200877static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
878{
879 __u8 status = *((__u8 *) skb->data);
880
881 BT_DBG("%s status 0x%x", hdev->name, status);
882
883 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
884}
885
886static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
887 struct sk_buff *skb)
888{
889 __u8 status = *((__u8 *) skb->data);
890
891 BT_DBG("%s status 0x%x", hdev->name, status);
892
893 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
894}
895
896static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
897 struct sk_buff *skb)
898{
899 __u8 status = *((__u8 *) skb->data);
900
901 BT_DBG("%s status 0x%x", hdev->name, status);
902
903 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
904}
905
906static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
907{
908 __u8 status = *((__u8 *) skb->data);
909
910 BT_DBG("%s status 0x%x", hdev->name, status);
911
912 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
913}
914
Johan Hedberg980e1a52011-01-22 06:10:07 +0200915static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
916{
917 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
918 struct hci_cp_pin_code_reply *cp;
919 struct hci_conn *conn;
920
921 BT_DBG("%s status 0x%x", hdev->name, rp->status);
922
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200923 hci_dev_lock(hdev);
924
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200925 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200926 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200927
928 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200929 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200930
931 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
932 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200933 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200934
935 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
936 if (conn)
937 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200938
939unlock:
940 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200941}
942
943static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
944{
945 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
946
947 BT_DBG("%s status 0x%x", hdev->name, rp->status);
948
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200949 hci_dev_lock(hdev);
950
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200951 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200952 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200953 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200954
955 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200956}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200957
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300958static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
959 struct sk_buff *skb)
960{
961 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
962
963 BT_DBG("%s status 0x%x", hdev->name, rp->status);
964
965 if (rp->status)
966 return;
967
968 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
969 hdev->le_pkts = rp->le_max_pkt;
970
971 hdev->le_cnt = hdev->le_pkts;
972
973 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
974
975 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
976}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200977
Johan Hedberga5c29682011-02-19 12:05:57 -0300978static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
979{
980 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
981
982 BT_DBG("%s status 0x%x", hdev->name, rp->status);
983
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200984 hci_dev_lock(hdev);
985
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200986 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200987 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
988 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200989
990 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300991}
992
993static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
994 struct sk_buff *skb)
995{
996 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
997
998 BT_DBG("%s status 0x%x", hdev->name, rp->status);
999
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001000 hci_dev_lock(hdev);
1001
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001002 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001003 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001004 ACL_LINK, 0,
Johan Hedberga5c29682011-02-19 12:05:57 -03001005 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001006
1007 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -03001008}
1009
Brian Gix1143d452011-11-23 08:28:34 -08001010static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
1011{
1012 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1013
1014 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1015
1016 hci_dev_lock(hdev);
1017
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001018 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001019 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1020 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001021
1022 hci_dev_unlock(hdev);
1023}
1024
1025static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1026 struct sk_buff *skb)
1027{
1028 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1029
1030 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1031
1032 hci_dev_lock(hdev);
1033
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001034 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001035 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001036 ACL_LINK, 0,
Brian Gix1143d452011-11-23 08:28:34 -08001037 rp->status);
1038
1039 hci_dev_unlock(hdev);
1040}
1041
Szymon Jancc35938b2011-03-22 13:12:21 +01001042static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1043 struct sk_buff *skb)
1044{
1045 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1046
1047 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1048
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001049 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001050 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001051 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001052 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001053}
1054
Andre Guedes07f7fa52011-12-02 21:13:31 +09001055static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1056{
1057 __u8 status = *((__u8 *) skb->data);
1058
1059 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001060
1061 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001062
1063 if (status) {
1064 hci_dev_lock(hdev);
1065 mgmt_start_discovery_failed(hdev, status);
1066 hci_dev_unlock(hdev);
1067 return;
1068 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001069}
1070
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001071static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1072 struct sk_buff *skb)
1073{
1074 struct hci_cp_le_set_scan_enable *cp;
1075 __u8 status = *((__u8 *) skb->data);
1076
1077 BT_DBG("%s status 0x%x", hdev->name, status);
1078
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001079 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1080 if (!cp)
1081 return;
1082
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001083 switch (cp->enable) {
1084 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001085 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1086
Andre Guedes3fd24152012-02-03 17:48:01 -03001087 if (status) {
1088 hci_dev_lock(hdev);
1089 mgmt_start_discovery_failed(hdev, status);
1090 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001091 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001092 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001093
Andre Guedesd23264a2011-11-25 20:53:38 -03001094 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1095
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001096 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001097
1098 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001099 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001100 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001101 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001102 break;
1103
1104 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001105 if (status)
1106 return;
1107
Andre Guedesd23264a2011-11-25 20:53:38 -03001108 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1109
Andre Guedesd0843292012-01-02 19:18:11 -03001110 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001111
1112 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1113 mgmt_interleaved_discovery(hdev);
1114 } else {
1115 hci_dev_lock(hdev);
1116 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1117 hci_dev_unlock(hdev);
1118 }
1119
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001120 break;
1121
1122 default:
1123 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1124 break;
Andre Guedes35815082011-05-26 16:23:53 -03001125 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001126}
1127
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001128static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1129{
1130 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1131
1132 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1133
1134 if (rp->status)
1135 return;
1136
1137 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1138}
1139
1140static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1141{
1142 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1143
1144 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1145
1146 if (rp->status)
1147 return;
1148
1149 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1150}
1151
Andre Guedesf9b49302011-06-30 19:20:53 -03001152static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1153 struct sk_buff *skb)
1154{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001155 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001156 __u8 status = *((__u8 *) skb->data);
1157
1158 BT_DBG("%s status 0x%x", hdev->name, status);
1159
Johan Hedberg06199cf2012-02-22 16:37:11 +02001160 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001161 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001162 return;
1163
Johan Hedberg8f984df2012-02-28 01:07:22 +02001164 if (!status) {
1165 if (sent->le)
1166 hdev->host_features[0] |= LMP_HOST_LE;
1167 else
1168 hdev->host_features[0] &= ~LMP_HOST_LE;
1169 }
1170
1171 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
1172 !test_bit(HCI_INIT, &hdev->flags))
1173 mgmt_le_enable_complete(hdev, sent->le, status);
1174
1175 hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001176}
1177
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001178static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1179{
1180 BT_DBG("%s status 0x%x", hdev->name, status);
1181
1182 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001183 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001184 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001185 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001186 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001187 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001188 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001189 return;
1190 }
1191
Andre Guedes89352e72011-11-04 14:16:53 -03001192 set_bit(HCI_INQUIRY, &hdev->flags);
1193
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001194 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001195 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001196 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001197}
1198
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1200{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001201 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001204 BT_DBG("%s status 0x%x", hdev->name, status);
1205
1206 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 if (!cp)
1208 return;
1209
1210 hci_dev_lock(hdev);
1211
1212 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1213
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001214 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215
1216 if (status) {
1217 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001218 if (status != 0x0c || conn->attempt > 2) {
1219 conn->state = BT_CLOSED;
1220 hci_proto_connect_cfm(conn, status);
1221 hci_conn_del(conn);
1222 } else
1223 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 }
1225 } else {
1226 if (!conn) {
1227 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1228 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001229 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230 conn->link_mode |= HCI_LM_MASTER;
1231 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001232 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 }
1234 }
1235
1236 hci_dev_unlock(hdev);
1237}
1238
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001239static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001241 struct hci_cp_add_sco *cp;
1242 struct hci_conn *acl, *sco;
1243 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001245 BT_DBG("%s status 0x%x", hdev->name, status);
1246
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001247 if (!status)
1248 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001250 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1251 if (!cp)
1252 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001254 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001256 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001257
1258 hci_dev_lock(hdev);
1259
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001260 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001261 if (acl) {
1262 sco = acl->link;
1263 if (sco) {
1264 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001265
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001266 hci_proto_connect_cfm(sco, status);
1267 hci_conn_del(sco);
1268 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001269 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001270
1271 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272}
1273
Marcel Holtmannf8558552008-07-14 20:13:49 +02001274static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1275{
1276 struct hci_cp_auth_requested *cp;
1277 struct hci_conn *conn;
1278
1279 BT_DBG("%s status 0x%x", hdev->name, status);
1280
1281 if (!status)
1282 return;
1283
1284 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1285 if (!cp)
1286 return;
1287
1288 hci_dev_lock(hdev);
1289
1290 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1291 if (conn) {
1292 if (conn->state == BT_CONFIG) {
1293 hci_proto_connect_cfm(conn, status);
1294 hci_conn_put(conn);
1295 }
1296 }
1297
1298 hci_dev_unlock(hdev);
1299}
1300
1301static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1302{
1303 struct hci_cp_set_conn_encrypt *cp;
1304 struct hci_conn *conn;
1305
1306 BT_DBG("%s status 0x%x", hdev->name, status);
1307
1308 if (!status)
1309 return;
1310
1311 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1312 if (!cp)
1313 return;
1314
1315 hci_dev_lock(hdev);
1316
1317 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1318 if (conn) {
1319 if (conn->state == BT_CONFIG) {
1320 hci_proto_connect_cfm(conn, status);
1321 hci_conn_put(conn);
1322 }
1323 }
1324
1325 hci_dev_unlock(hdev);
1326}
1327
Johan Hedberg127178d2010-11-18 22:22:29 +02001328static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001329 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001330{
Johan Hedberg392599b2010-11-18 22:22:28 +02001331 if (conn->state != BT_CONFIG || !conn->out)
1332 return 0;
1333
Johan Hedberg765c2a92011-01-19 12:06:52 +05301334 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001335 return 0;
1336
1337 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001338 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001339 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001340 conn->pending_sec_level != BT_SECURITY_HIGH &&
1341 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001342 return 0;
1343
Johan Hedberg392599b2010-11-18 22:22:28 +02001344 return 1;
1345}
1346
Gustavo F. Padovan00abfe42012-03-01 00:37:10 -03001347static inline int hci_resolve_name(struct hci_dev *hdev,
1348 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001349{
1350 struct hci_cp_remote_name_req cp;
1351
1352 memset(&cp, 0, sizeof(cp));
1353
1354 bacpy(&cp.bdaddr, &e->data.bdaddr);
1355 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1356 cp.pscan_mode = e->data.pscan_mode;
1357 cp.clock_offset = e->data.clock_offset;
1358
1359 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1360}
1361
Johan Hedbergb644ba32012-01-17 21:48:47 +02001362static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001363{
1364 struct discovery_state *discov = &hdev->discovery;
1365 struct inquiry_entry *e;
1366
Johan Hedbergb644ba32012-01-17 21:48:47 +02001367 if (list_empty(&discov->resolve))
1368 return false;
1369
1370 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1371 if (hci_resolve_name(hdev, e) == 0) {
1372 e->name_state = NAME_PENDING;
1373 return true;
1374 }
1375
1376 return false;
1377}
1378
1379static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1380 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1381{
1382 struct discovery_state *discov = &hdev->discovery;
1383 struct inquiry_entry *e;
1384
1385 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Johan Hedberg08c79b62012-02-23 22:31:51 +02001386 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0,
Johan Hedbergb644ba32012-01-17 21:48:47 +02001387 name, name_len, conn->dev_class);
1388
1389 if (discov->state == DISCOVERY_STOPPED)
1390 return;
1391
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001392 if (discov->state == DISCOVERY_STOPPING)
1393 goto discov_complete;
1394
1395 if (discov->state != DISCOVERY_RESOLVING)
1396 return;
1397
1398 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1399 if (e) {
1400 e->name_state = NAME_KNOWN;
1401 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001402 if (name)
1403 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1404 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001405 }
1406
Johan Hedbergb644ba32012-01-17 21:48:47 +02001407 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001408 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001409
1410discov_complete:
1411 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1412}
1413
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001414static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1415{
Johan Hedberg127178d2010-11-18 22:22:29 +02001416 struct hci_cp_remote_name_req *cp;
1417 struct hci_conn *conn;
1418
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001419 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001420
1421 /* If successful wait for the name req complete event before
1422 * checking for the need to do authentication */
1423 if (!status)
1424 return;
1425
1426 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1427 if (!cp)
1428 return;
1429
1430 hci_dev_lock(hdev);
1431
1432 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001433
1434 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1435 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1436
Johan Hedberg79c6c702011-04-28 11:28:55 -07001437 if (!conn)
1438 goto unlock;
1439
1440 if (!hci_outgoing_auth_needed(hdev, conn))
1441 goto unlock;
1442
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001443 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001444 struct hci_cp_auth_requested cp;
1445 cp.handle = __cpu_to_le16(conn->handle);
1446 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1447 }
1448
Johan Hedberg79c6c702011-04-28 11:28:55 -07001449unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001450 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001451}
1452
Marcel Holtmann769be972008-07-14 20:13:49 +02001453static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1454{
1455 struct hci_cp_read_remote_features *cp;
1456 struct hci_conn *conn;
1457
1458 BT_DBG("%s status 0x%x", hdev->name, status);
1459
1460 if (!status)
1461 return;
1462
1463 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1464 if (!cp)
1465 return;
1466
1467 hci_dev_lock(hdev);
1468
1469 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1470 if (conn) {
1471 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001472 hci_proto_connect_cfm(conn, status);
1473 hci_conn_put(conn);
1474 }
1475 }
1476
1477 hci_dev_unlock(hdev);
1478}
1479
1480static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1481{
1482 struct hci_cp_read_remote_ext_features *cp;
1483 struct hci_conn *conn;
1484
1485 BT_DBG("%s status 0x%x", hdev->name, status);
1486
1487 if (!status)
1488 return;
1489
1490 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1491 if (!cp)
1492 return;
1493
1494 hci_dev_lock(hdev);
1495
1496 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1497 if (conn) {
1498 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001499 hci_proto_connect_cfm(conn, status);
1500 hci_conn_put(conn);
1501 }
1502 }
1503
1504 hci_dev_unlock(hdev);
1505}
1506
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001507static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1508{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001509 struct hci_cp_setup_sync_conn *cp;
1510 struct hci_conn *acl, *sco;
1511 __u16 handle;
1512
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001513 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001514
1515 if (!status)
1516 return;
1517
1518 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1519 if (!cp)
1520 return;
1521
1522 handle = __le16_to_cpu(cp->handle);
1523
1524 BT_DBG("%s handle %d", hdev->name, handle);
1525
1526 hci_dev_lock(hdev);
1527
1528 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001529 if (acl) {
1530 sco = acl->link;
1531 if (sco) {
1532 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001533
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001534 hci_proto_connect_cfm(sco, status);
1535 hci_conn_del(sco);
1536 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001537 }
1538
1539 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001540}
1541
1542static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1543{
1544 struct hci_cp_sniff_mode *cp;
1545 struct hci_conn *conn;
1546
1547 BT_DBG("%s status 0x%x", hdev->name, status);
1548
1549 if (!status)
1550 return;
1551
1552 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1553 if (!cp)
1554 return;
1555
1556 hci_dev_lock(hdev);
1557
1558 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001559 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001560 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001561
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001562 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001563 hci_sco_setup(conn, status);
1564 }
1565
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001566 hci_dev_unlock(hdev);
1567}
1568
1569static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1570{
1571 struct hci_cp_exit_sniff_mode *cp;
1572 struct hci_conn *conn;
1573
1574 BT_DBG("%s status 0x%x", hdev->name, status);
1575
1576 if (!status)
1577 return;
1578
1579 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1580 if (!cp)
1581 return;
1582
1583 hci_dev_lock(hdev);
1584
1585 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001586 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001587 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001588
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001589 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001590 hci_sco_setup(conn, status);
1591 }
1592
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001593 hci_dev_unlock(hdev);
1594}
1595
Johan Hedberg88c3df12012-02-09 14:27:38 +02001596static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1597{
1598 struct hci_cp_disconnect *cp;
1599 struct hci_conn *conn;
1600
1601 if (!status)
1602 return;
1603
1604 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1605 if (!cp)
1606 return;
1607
1608 hci_dev_lock(hdev);
1609
1610 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1611 if (conn)
1612 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1613 conn->dst_type, status);
1614
1615 hci_dev_unlock(hdev);
1616}
1617
Ville Tervofcd89c02011-02-10 22:38:47 -03001618static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1619{
1620 struct hci_cp_le_create_conn *cp;
1621 struct hci_conn *conn;
1622
1623 BT_DBG("%s status 0x%x", hdev->name, status);
1624
1625 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1626 if (!cp)
1627 return;
1628
1629 hci_dev_lock(hdev);
1630
1631 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1632
1633 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1634 conn);
1635
1636 if (status) {
1637 if (conn && conn->state == BT_CONNECT) {
1638 conn->state = BT_CLOSED;
1639 hci_proto_connect_cfm(conn, status);
1640 hci_conn_del(conn);
1641 }
1642 } else {
1643 if (!conn) {
1644 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001645 if (conn) {
1646 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001647 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001648 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001649 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001650 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001651 }
1652 }
1653
1654 hci_dev_unlock(hdev);
1655}
1656
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001657static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1658{
1659 BT_DBG("%s status 0x%x", hdev->name, status);
1660}
1661
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001662static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1663{
1664 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001665 struct discovery_state *discov = &hdev->discovery;
1666 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001667
1668 BT_DBG("%s status %d", hdev->name, status);
1669
Johan Hedberg23bb5762010-12-21 23:01:27 +02001670 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001671
1672 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001673
1674 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1675 return;
1676
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001677 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001678 return;
1679
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001680 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001681
Andre Guedes343f9352012-02-17 20:39:37 -03001682 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001683 goto unlock;
1684
1685 if (list_empty(&discov->resolve)) {
1686 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1687 goto unlock;
1688 }
1689
1690 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1691 if (e && hci_resolve_name(hdev, e) == 0) {
1692 e->name_state = NAME_PENDING;
1693 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1694 } else {
1695 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1696 }
1697
1698unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001699 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001700}
1701
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1703{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001704 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001705 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 int num_rsp = *((__u8 *) skb->data);
1707
1708 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1709
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001710 if (!num_rsp)
1711 return;
1712
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001714
Johan Hedberge17acd42011-03-30 23:57:16 +03001715 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001716 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001717
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 bacpy(&data.bdaddr, &info->bdaddr);
1719 data.pscan_rep_mode = info->pscan_rep_mode;
1720 data.pscan_period_mode = info->pscan_period_mode;
1721 data.pscan_mode = info->pscan_mode;
1722 memcpy(data.dev_class, info->dev_class, 3);
1723 data.clock_offset = info->clock_offset;
1724 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001725 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001726
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001727 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001728 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001729 info->dev_class, 0, !name_known, ssp,
Andre Guedes7d262f82012-01-10 18:20:49 -03001730 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001732
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 hci_dev_unlock(hdev);
1734}
1735
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001736static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001738 struct hci_ev_conn_complete *ev = (void *) skb->data;
1739 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001741 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001742
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001744
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001745 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001746 if (!conn) {
1747 if (ev->link_type != SCO_LINK)
1748 goto unlock;
1749
1750 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1751 if (!conn)
1752 goto unlock;
1753
1754 conn->type = SCO_LINK;
1755 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001756
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001757 if (!ev->status) {
1758 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001759
1760 if (conn->type == ACL_LINK) {
1761 conn->state = BT_CONFIG;
1762 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001763 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001764 } else
1765 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001766
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001767 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001768 hci_conn_add_sysfs(conn);
1769
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001770 if (test_bit(HCI_AUTH, &hdev->flags))
1771 conn->link_mode |= HCI_LM_AUTH;
1772
1773 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1774 conn->link_mode |= HCI_LM_ENCRYPT;
1775
1776 /* Get remote features */
1777 if (conn->type == ACL_LINK) {
1778 struct hci_cp_read_remote_features cp;
1779 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001780 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1781 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001782 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001783
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001784 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001785 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001786 struct hci_cp_change_conn_ptype cp;
1787 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001788 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1789 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1790 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001791 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001792 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001793 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001794 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001795 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001796 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001797 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001798
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001799 if (conn->type == ACL_LINK)
1800 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001801
Marcel Holtmann769be972008-07-14 20:13:49 +02001802 if (ev->status) {
1803 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001804 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001805 } else if (ev->link_type != ACL_LINK)
1806 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001807
1808unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001810
1811 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812}
1813
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1815{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001816 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 int mask = hdev->link_mode;
1818
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001819 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1820 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821
1822 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1823
Szymon Janc138d22e2011-02-17 16:44:23 +01001824 if ((mask & HCI_LM_ACCEPT) &&
1825 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001827 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
1830 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001831
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001832 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1833 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001834 memcpy(ie->data.dev_class, ev->dev_class, 3);
1835
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1837 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001838 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1839 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001840 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 hci_dev_unlock(hdev);
1842 return;
1843 }
1844 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001845
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 memcpy(conn->dev_class, ev->dev_class, 3);
1847 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001848
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 hci_dev_unlock(hdev);
1850
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001851 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1852 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001854 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001856 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1857 cp.role = 0x00; /* Become master */
1858 else
1859 cp.role = 0x01; /* Remain slave */
1860
1861 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1862 sizeof(cp), &cp);
1863 } else {
1864 struct hci_cp_accept_sync_conn_req cp;
1865
1866 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001867 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001868
1869 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1870 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1871 cp.max_latency = cpu_to_le16(0xffff);
1872 cp.content_format = cpu_to_le16(hdev->voice_setting);
1873 cp.retrans_effort = 0xff;
1874
1875 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1876 sizeof(cp), &cp);
1877 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 } else {
1879 /* Connection rejected */
1880 struct hci_cp_reject_conn_req cp;
1881
1882 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001883 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001884 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 }
1886}
1887
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1889{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001890 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001891 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892
1893 BT_DBG("%s status %d", hdev->name, ev->status);
1894
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 hci_dev_lock(hdev);
1896
Marcel Holtmann04837f62006-07-03 10:02:33 +02001897 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001898 if (!conn)
1899 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001900
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001901 if (ev->status == 0)
1902 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903
Johan Hedbergb644ba32012-01-17 21:48:47 +02001904 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1905 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001906 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001907 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1908 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001909 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001910 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001911 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001912 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001913
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001914 if (ev->status == 0) {
1915 hci_proto_disconn_cfm(conn, ev->reason);
1916 hci_conn_del(conn);
1917 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001918
1919unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 hci_dev_unlock(hdev);
1921}
1922
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001923static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1924{
1925 struct hci_ev_auth_complete *ev = (void *) skb->data;
1926 struct hci_conn *conn;
1927
1928 BT_DBG("%s status %d", hdev->name, ev->status);
1929
1930 hci_dev_lock(hdev);
1931
1932 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001933 if (!conn)
1934 goto unlock;
1935
1936 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001937 if (!hci_conn_ssp_enabled(conn) &&
1938 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001939 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001940 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001941 conn->link_mode |= HCI_LM_AUTH;
1942 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001943 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001944 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001945 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
1946 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001947 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001948
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001949 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1950 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001951
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001952 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001953 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001954 struct hci_cp_set_conn_encrypt cp;
1955 cp.handle = ev->handle;
1956 cp.encrypt = 0x01;
1957 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1958 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001959 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001960 conn->state = BT_CONNECTED;
1961 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001962 hci_conn_put(conn);
1963 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001964 } else {
1965 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001966
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001967 hci_conn_hold(conn);
1968 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1969 hci_conn_put(conn);
1970 }
1971
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001972 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001973 if (!ev->status) {
1974 struct hci_cp_set_conn_encrypt cp;
1975 cp.handle = ev->handle;
1976 cp.encrypt = 0x01;
1977 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1978 &cp);
1979 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001980 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001981 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001982 }
1983 }
1984
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001985unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001986 hci_dev_unlock(hdev);
1987}
1988
1989static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1990{
Johan Hedberg127178d2010-11-18 22:22:29 +02001991 struct hci_ev_remote_name *ev = (void *) skb->data;
1992 struct hci_conn *conn;
1993
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001994 BT_DBG("%s", hdev->name);
1995
1996 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001997
1998 hci_dev_lock(hdev);
1999
2000 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002001
2002 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2003 goto check_auth;
2004
2005 if (ev->status == 0)
2006 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
2007 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
2008 else
2009 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2010
2011check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002012 if (!conn)
2013 goto unlock;
2014
2015 if (!hci_outgoing_auth_needed(hdev, conn))
2016 goto unlock;
2017
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002018 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002019 struct hci_cp_auth_requested cp;
2020 cp.handle = __cpu_to_le16(conn->handle);
2021 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2022 }
2023
Johan Hedberg79c6c702011-04-28 11:28:55 -07002024unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002025 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002026}
2027
2028static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2029{
2030 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2031 struct hci_conn *conn;
2032
2033 BT_DBG("%s status %d", hdev->name, ev->status);
2034
2035 hci_dev_lock(hdev);
2036
2037 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2038 if (conn) {
2039 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002040 if (ev->encrypt) {
2041 /* Encryption implies authentication */
2042 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002043 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002044 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002045 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002046 conn->link_mode &= ~HCI_LM_ENCRYPT;
2047 }
2048
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002049 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002050
Marcel Holtmannf8558552008-07-14 20:13:49 +02002051 if (conn->state == BT_CONFIG) {
2052 if (!ev->status)
2053 conn->state = BT_CONNECTED;
2054
2055 hci_proto_connect_cfm(conn, ev->status);
2056 hci_conn_put(conn);
2057 } else
2058 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002059 }
2060
2061 hci_dev_unlock(hdev);
2062}
2063
2064static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2065{
2066 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2067 struct hci_conn *conn;
2068
2069 BT_DBG("%s status %d", hdev->name, ev->status);
2070
2071 hci_dev_lock(hdev);
2072
2073 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2074 if (conn) {
2075 if (!ev->status)
2076 conn->link_mode |= HCI_LM_SECURE;
2077
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002078 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002079
2080 hci_key_change_cfm(conn, ev->status);
2081 }
2082
2083 hci_dev_unlock(hdev);
2084}
2085
2086static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2087{
2088 struct hci_ev_remote_features *ev = (void *) skb->data;
2089 struct hci_conn *conn;
2090
2091 BT_DBG("%s status %d", hdev->name, ev->status);
2092
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002093 hci_dev_lock(hdev);
2094
2095 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002096 if (!conn)
2097 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002098
Johan Hedbergccd556f2010-11-10 17:11:51 +02002099 if (!ev->status)
2100 memcpy(conn->features, ev->features, 8);
2101
2102 if (conn->state != BT_CONFIG)
2103 goto unlock;
2104
2105 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2106 struct hci_cp_read_remote_ext_features cp;
2107 cp.handle = ev->handle;
2108 cp.page = 0x01;
2109 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002110 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002111 goto unlock;
2112 }
2113
Johan Hedberg127178d2010-11-18 22:22:29 +02002114 if (!ev->status) {
2115 struct hci_cp_remote_name_req cp;
2116 memset(&cp, 0, sizeof(cp));
2117 bacpy(&cp.bdaddr, &conn->dst);
2118 cp.pscan_rep_mode = 0x02;
2119 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002120 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2121 mgmt_device_connected(hdev, &conn->dst, conn->type,
Johan Hedberg08c79b62012-02-23 22:31:51 +02002122 conn->dst_type, 0, NULL, 0,
Johan Hedbergb644ba32012-01-17 21:48:47 +02002123 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002124
Johan Hedberg127178d2010-11-18 22:22:29 +02002125 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002126 conn->state = BT_CONNECTED;
2127 hci_proto_connect_cfm(conn, ev->status);
2128 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002129 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002130
Johan Hedbergccd556f2010-11-10 17:11:51 +02002131unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002132 hci_dev_unlock(hdev);
2133}
2134
2135static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2136{
2137 BT_DBG("%s", hdev->name);
2138}
2139
2140static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2141{
2142 BT_DBG("%s", hdev->name);
2143}
2144
2145static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2146{
2147 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2148 __u16 opcode;
2149
2150 skb_pull(skb, sizeof(*ev));
2151
2152 opcode = __le16_to_cpu(ev->opcode);
2153
2154 switch (opcode) {
2155 case HCI_OP_INQUIRY_CANCEL:
2156 hci_cc_inquiry_cancel(hdev, skb);
2157 break;
2158
2159 case HCI_OP_EXIT_PERIODIC_INQ:
2160 hci_cc_exit_periodic_inq(hdev, skb);
2161 break;
2162
2163 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2164 hci_cc_remote_name_req_cancel(hdev, skb);
2165 break;
2166
2167 case HCI_OP_ROLE_DISCOVERY:
2168 hci_cc_role_discovery(hdev, skb);
2169 break;
2170
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002171 case HCI_OP_READ_LINK_POLICY:
2172 hci_cc_read_link_policy(hdev, skb);
2173 break;
2174
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002175 case HCI_OP_WRITE_LINK_POLICY:
2176 hci_cc_write_link_policy(hdev, skb);
2177 break;
2178
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002179 case HCI_OP_READ_DEF_LINK_POLICY:
2180 hci_cc_read_def_link_policy(hdev, skb);
2181 break;
2182
2183 case HCI_OP_WRITE_DEF_LINK_POLICY:
2184 hci_cc_write_def_link_policy(hdev, skb);
2185 break;
2186
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002187 case HCI_OP_RESET:
2188 hci_cc_reset(hdev, skb);
2189 break;
2190
2191 case HCI_OP_WRITE_LOCAL_NAME:
2192 hci_cc_write_local_name(hdev, skb);
2193 break;
2194
2195 case HCI_OP_READ_LOCAL_NAME:
2196 hci_cc_read_local_name(hdev, skb);
2197 break;
2198
2199 case HCI_OP_WRITE_AUTH_ENABLE:
2200 hci_cc_write_auth_enable(hdev, skb);
2201 break;
2202
2203 case HCI_OP_WRITE_ENCRYPT_MODE:
2204 hci_cc_write_encrypt_mode(hdev, skb);
2205 break;
2206
2207 case HCI_OP_WRITE_SCAN_ENABLE:
2208 hci_cc_write_scan_enable(hdev, skb);
2209 break;
2210
2211 case HCI_OP_READ_CLASS_OF_DEV:
2212 hci_cc_read_class_of_dev(hdev, skb);
2213 break;
2214
2215 case HCI_OP_WRITE_CLASS_OF_DEV:
2216 hci_cc_write_class_of_dev(hdev, skb);
2217 break;
2218
2219 case HCI_OP_READ_VOICE_SETTING:
2220 hci_cc_read_voice_setting(hdev, skb);
2221 break;
2222
2223 case HCI_OP_WRITE_VOICE_SETTING:
2224 hci_cc_write_voice_setting(hdev, skb);
2225 break;
2226
2227 case HCI_OP_HOST_BUFFER_SIZE:
2228 hci_cc_host_buffer_size(hdev, skb);
2229 break;
2230
Marcel Holtmann333140b2008-07-14 20:13:48 +02002231 case HCI_OP_WRITE_SSP_MODE:
2232 hci_cc_write_ssp_mode(hdev, skb);
2233 break;
2234
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002235 case HCI_OP_READ_LOCAL_VERSION:
2236 hci_cc_read_local_version(hdev, skb);
2237 break;
2238
2239 case HCI_OP_READ_LOCAL_COMMANDS:
2240 hci_cc_read_local_commands(hdev, skb);
2241 break;
2242
2243 case HCI_OP_READ_LOCAL_FEATURES:
2244 hci_cc_read_local_features(hdev, skb);
2245 break;
2246
Andre Guedes971e3a42011-06-30 19:20:52 -03002247 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2248 hci_cc_read_local_ext_features(hdev, skb);
2249 break;
2250
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002251 case HCI_OP_READ_BUFFER_SIZE:
2252 hci_cc_read_buffer_size(hdev, skb);
2253 break;
2254
2255 case HCI_OP_READ_BD_ADDR:
2256 hci_cc_read_bd_addr(hdev, skb);
2257 break;
2258
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002259 case HCI_OP_READ_DATA_BLOCK_SIZE:
2260 hci_cc_read_data_block_size(hdev, skb);
2261 break;
2262
Johan Hedberg23bb5762010-12-21 23:01:27 +02002263 case HCI_OP_WRITE_CA_TIMEOUT:
2264 hci_cc_write_ca_timeout(hdev, skb);
2265 break;
2266
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002267 case HCI_OP_READ_FLOW_CONTROL_MODE:
2268 hci_cc_read_flow_control_mode(hdev, skb);
2269 break;
2270
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002271 case HCI_OP_READ_LOCAL_AMP_INFO:
2272 hci_cc_read_local_amp_info(hdev, skb);
2273 break;
2274
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002275 case HCI_OP_DELETE_STORED_LINK_KEY:
2276 hci_cc_delete_stored_link_key(hdev, skb);
2277 break;
2278
Johan Hedbergd5859e22011-01-25 01:19:58 +02002279 case HCI_OP_SET_EVENT_MASK:
2280 hci_cc_set_event_mask(hdev, skb);
2281 break;
2282
2283 case HCI_OP_WRITE_INQUIRY_MODE:
2284 hci_cc_write_inquiry_mode(hdev, skb);
2285 break;
2286
2287 case HCI_OP_READ_INQ_RSP_TX_POWER:
2288 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2289 break;
2290
2291 case HCI_OP_SET_EVENT_FLT:
2292 hci_cc_set_event_flt(hdev, skb);
2293 break;
2294
Johan Hedberg980e1a52011-01-22 06:10:07 +02002295 case HCI_OP_PIN_CODE_REPLY:
2296 hci_cc_pin_code_reply(hdev, skb);
2297 break;
2298
2299 case HCI_OP_PIN_CODE_NEG_REPLY:
2300 hci_cc_pin_code_neg_reply(hdev, skb);
2301 break;
2302
Szymon Jancc35938b2011-03-22 13:12:21 +01002303 case HCI_OP_READ_LOCAL_OOB_DATA:
2304 hci_cc_read_local_oob_data_reply(hdev, skb);
2305 break;
2306
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002307 case HCI_OP_LE_READ_BUFFER_SIZE:
2308 hci_cc_le_read_buffer_size(hdev, skb);
2309 break;
2310
Johan Hedberga5c29682011-02-19 12:05:57 -03002311 case HCI_OP_USER_CONFIRM_REPLY:
2312 hci_cc_user_confirm_reply(hdev, skb);
2313 break;
2314
2315 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2316 hci_cc_user_confirm_neg_reply(hdev, skb);
2317 break;
2318
Brian Gix1143d452011-11-23 08:28:34 -08002319 case HCI_OP_USER_PASSKEY_REPLY:
2320 hci_cc_user_passkey_reply(hdev, skb);
2321 break;
2322
2323 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2324 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002325
2326 case HCI_OP_LE_SET_SCAN_PARAM:
2327 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002328 break;
2329
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002330 case HCI_OP_LE_SET_SCAN_ENABLE:
2331 hci_cc_le_set_scan_enable(hdev, skb);
2332 break;
2333
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002334 case HCI_OP_LE_LTK_REPLY:
2335 hci_cc_le_ltk_reply(hdev, skb);
2336 break;
2337
2338 case HCI_OP_LE_LTK_NEG_REPLY:
2339 hci_cc_le_ltk_neg_reply(hdev, skb);
2340 break;
2341
Andre Guedesf9b49302011-06-30 19:20:53 -03002342 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2343 hci_cc_write_le_host_supported(hdev, skb);
2344 break;
2345
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002346 default:
2347 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2348 break;
2349 }
2350
Ville Tervo6bd32322011-02-16 16:32:41 +02002351 if (ev->opcode != HCI_OP_NOP)
2352 del_timer(&hdev->cmd_timer);
2353
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002354 if (ev->ncmd) {
2355 atomic_set(&hdev->cmd_cnt, 1);
2356 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002357 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002358 }
2359}
2360
2361static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2362{
2363 struct hci_ev_cmd_status *ev = (void *) skb->data;
2364 __u16 opcode;
2365
2366 skb_pull(skb, sizeof(*ev));
2367
2368 opcode = __le16_to_cpu(ev->opcode);
2369
2370 switch (opcode) {
2371 case HCI_OP_INQUIRY:
2372 hci_cs_inquiry(hdev, ev->status);
2373 break;
2374
2375 case HCI_OP_CREATE_CONN:
2376 hci_cs_create_conn(hdev, ev->status);
2377 break;
2378
2379 case HCI_OP_ADD_SCO:
2380 hci_cs_add_sco(hdev, ev->status);
2381 break;
2382
Marcel Holtmannf8558552008-07-14 20:13:49 +02002383 case HCI_OP_AUTH_REQUESTED:
2384 hci_cs_auth_requested(hdev, ev->status);
2385 break;
2386
2387 case HCI_OP_SET_CONN_ENCRYPT:
2388 hci_cs_set_conn_encrypt(hdev, ev->status);
2389 break;
2390
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002391 case HCI_OP_REMOTE_NAME_REQ:
2392 hci_cs_remote_name_req(hdev, ev->status);
2393 break;
2394
Marcel Holtmann769be972008-07-14 20:13:49 +02002395 case HCI_OP_READ_REMOTE_FEATURES:
2396 hci_cs_read_remote_features(hdev, ev->status);
2397 break;
2398
2399 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2400 hci_cs_read_remote_ext_features(hdev, ev->status);
2401 break;
2402
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002403 case HCI_OP_SETUP_SYNC_CONN:
2404 hci_cs_setup_sync_conn(hdev, ev->status);
2405 break;
2406
2407 case HCI_OP_SNIFF_MODE:
2408 hci_cs_sniff_mode(hdev, ev->status);
2409 break;
2410
2411 case HCI_OP_EXIT_SNIFF_MODE:
2412 hci_cs_exit_sniff_mode(hdev, ev->status);
2413 break;
2414
Johan Hedberg8962ee72011-01-20 12:40:27 +02002415 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002416 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002417 break;
2418
Ville Tervofcd89c02011-02-10 22:38:47 -03002419 case HCI_OP_LE_CREATE_CONN:
2420 hci_cs_le_create_conn(hdev, ev->status);
2421 break;
2422
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002423 case HCI_OP_LE_START_ENC:
2424 hci_cs_le_start_enc(hdev, ev->status);
2425 break;
2426
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002427 default:
2428 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2429 break;
2430 }
2431
Ville Tervo6bd32322011-02-16 16:32:41 +02002432 if (ev->opcode != HCI_OP_NOP)
2433 del_timer(&hdev->cmd_timer);
2434
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002435 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002436 atomic_set(&hdev->cmd_cnt, 1);
2437 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002438 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002439 }
2440}
2441
2442static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2443{
2444 struct hci_ev_role_change *ev = (void *) skb->data;
2445 struct hci_conn *conn;
2446
2447 BT_DBG("%s status %d", hdev->name, ev->status);
2448
2449 hci_dev_lock(hdev);
2450
2451 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2452 if (conn) {
2453 if (!ev->status) {
2454 if (ev->role)
2455 conn->link_mode &= ~HCI_LM_MASTER;
2456 else
2457 conn->link_mode |= HCI_LM_MASTER;
2458 }
2459
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002460 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002461
2462 hci_role_switch_cfm(conn, ev->status, ev->role);
2463 }
2464
2465 hci_dev_unlock(hdev);
2466}
2467
Linus Torvalds1da177e2005-04-16 15:20:36 -07002468static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2469{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002470 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002471 int i;
2472
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002473 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2474 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2475 return;
2476 }
2477
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002478 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2479 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002480 BT_DBG("%s bad parameters", hdev->name);
2481 return;
2482 }
2483
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002484 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2485
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002486 for (i = 0; i < ev->num_hndl; i++) {
2487 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002488 struct hci_conn *conn;
2489 __u16 handle, count;
2490
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002491 handle = __le16_to_cpu(info->handle);
2492 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002493
2494 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002495 if (!conn)
2496 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002497
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002498 conn->sent -= count;
2499
2500 switch (conn->type) {
2501 case ACL_LINK:
2502 hdev->acl_cnt += count;
2503 if (hdev->acl_cnt > hdev->acl_pkts)
2504 hdev->acl_cnt = hdev->acl_pkts;
2505 break;
2506
2507 case LE_LINK:
2508 if (hdev->le_pkts) {
2509 hdev->le_cnt += count;
2510 if (hdev->le_cnt > hdev->le_pkts)
2511 hdev->le_cnt = hdev->le_pkts;
2512 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002513 hdev->acl_cnt += count;
2514 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515 hdev->acl_cnt = hdev->acl_pkts;
2516 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002517 break;
2518
2519 case SCO_LINK:
2520 hdev->sco_cnt += count;
2521 if (hdev->sco_cnt > hdev->sco_pkts)
2522 hdev->sco_cnt = hdev->sco_pkts;
2523 break;
2524
2525 default:
2526 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2527 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528 }
2529 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002530
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002531 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532}
2533
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002534static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2535 struct sk_buff *skb)
2536{
2537 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2538 int i;
2539
2540 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2541 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2542 return;
2543 }
2544
2545 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2546 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2547 BT_DBG("%s bad parameters", hdev->name);
2548 return;
2549 }
2550
2551 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2552 ev->num_hndl);
2553
2554 for (i = 0; i < ev->num_hndl; i++) {
2555 struct hci_comp_blocks_info *info = &ev->handles[i];
2556 struct hci_conn *conn;
2557 __u16 handle, block_count;
2558
2559 handle = __le16_to_cpu(info->handle);
2560 block_count = __le16_to_cpu(info->blocks);
2561
2562 conn = hci_conn_hash_lookup_handle(hdev, handle);
2563 if (!conn)
2564 continue;
2565
2566 conn->sent -= block_count;
2567
2568 switch (conn->type) {
2569 case ACL_LINK:
2570 hdev->block_cnt += block_count;
2571 if (hdev->block_cnt > hdev->num_blocks)
2572 hdev->block_cnt = hdev->num_blocks;
2573 break;
2574
2575 default:
2576 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2577 break;
2578 }
2579 }
2580
2581 queue_work(hdev->workqueue, &hdev->tx_work);
2582}
2583
Marcel Holtmann04837f62006-07-03 10:02:33 +02002584static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002585{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002586 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002587 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002588
2589 BT_DBG("%s status %d", hdev->name, ev->status);
2590
2591 hci_dev_lock(hdev);
2592
Marcel Holtmann04837f62006-07-03 10:02:33 +02002593 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2594 if (conn) {
2595 conn->mode = ev->mode;
2596 conn->interval = __le16_to_cpu(ev->interval);
2597
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002598 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002599 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002600 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002601 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002602 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002603 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002604
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002605 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002606 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002607 }
2608
2609 hci_dev_unlock(hdev);
2610}
2611
Linus Torvalds1da177e2005-04-16 15:20:36 -07002612static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2613{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002614 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2615 struct hci_conn *conn;
2616
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002617 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002618
2619 hci_dev_lock(hdev);
2620
2621 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002622 if (!conn)
2623 goto unlock;
2624
2625 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002626 hci_conn_hold(conn);
2627 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2628 hci_conn_put(conn);
2629 }
2630
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002631 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002632 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2633 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002634 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002635 u8 secure;
2636
2637 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2638 secure = 1;
2639 else
2640 secure = 0;
2641
Johan Hedberg744cf192011-11-08 20:40:14 +02002642 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002643 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002644
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002645unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002646 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002647}
2648
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2650{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002651 struct hci_ev_link_key_req *ev = (void *) skb->data;
2652 struct hci_cp_link_key_reply cp;
2653 struct hci_conn *conn;
2654 struct link_key *key;
2655
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002656 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002657
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002658 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002659 return;
2660
2661 hci_dev_lock(hdev);
2662
2663 key = hci_find_link_key(hdev, &ev->bdaddr);
2664 if (!key) {
2665 BT_DBG("%s link key not found for %s", hdev->name,
2666 batostr(&ev->bdaddr));
2667 goto not_found;
2668 }
2669
2670 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2671 batostr(&ev->bdaddr));
2672
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002673 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002674 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002675 BT_DBG("%s ignoring debug key", hdev->name);
2676 goto not_found;
2677 }
2678
2679 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002680 if (conn) {
2681 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2682 conn->auth_type != 0xff &&
2683 (conn->auth_type & 0x01)) {
2684 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2685 goto not_found;
2686 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002687
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002688 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2689 conn->pending_sec_level == BT_SECURITY_HIGH) {
2690 BT_DBG("%s ignoring key unauthenticated for high \
2691 security", hdev->name);
2692 goto not_found;
2693 }
2694
2695 conn->key_type = key->type;
2696 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002697 }
2698
2699 bacpy(&cp.bdaddr, &ev->bdaddr);
2700 memcpy(cp.link_key, key->val, 16);
2701
2702 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2703
2704 hci_dev_unlock(hdev);
2705
2706 return;
2707
2708not_found:
2709 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2710 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002711}
2712
Linus Torvalds1da177e2005-04-16 15:20:36 -07002713static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2714{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002715 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2716 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002717 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002718
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002719 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002720
2721 hci_dev_lock(hdev);
2722
2723 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2724 if (conn) {
2725 hci_conn_hold(conn);
2726 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002727 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002728
2729 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2730 conn->key_type = ev->key_type;
2731
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002732 hci_conn_put(conn);
2733 }
2734
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002735 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002736 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002737 ev->key_type, pin_len);
2738
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002739 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740}
2741
Marcel Holtmann04837f62006-07-03 10:02:33 +02002742static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2743{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002744 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002745 struct hci_conn *conn;
2746
2747 BT_DBG("%s status %d", hdev->name, ev->status);
2748
2749 hci_dev_lock(hdev);
2750
2751 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002752 if (conn && !ev->status) {
2753 struct inquiry_entry *ie;
2754
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002755 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2756 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002757 ie->data.clock_offset = ev->clock_offset;
2758 ie->timestamp = jiffies;
2759 }
2760 }
2761
2762 hci_dev_unlock(hdev);
2763}
2764
Marcel Holtmanna8746412008-07-14 20:13:46 +02002765static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2766{
2767 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2768 struct hci_conn *conn;
2769
2770 BT_DBG("%s status %d", hdev->name, ev->status);
2771
2772 hci_dev_lock(hdev);
2773
2774 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2775 if (conn && !ev->status)
2776 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2777
2778 hci_dev_unlock(hdev);
2779}
2780
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002781static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2782{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002783 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002784 struct inquiry_entry *ie;
2785
2786 BT_DBG("%s", hdev->name);
2787
2788 hci_dev_lock(hdev);
2789
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002790 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2791 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002792 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2793 ie->timestamp = jiffies;
2794 }
2795
2796 hci_dev_unlock(hdev);
2797}
2798
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002799static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2800{
2801 struct inquiry_data data;
2802 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002803 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002804
2805 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2806
2807 if (!num_rsp)
2808 return;
2809
2810 hci_dev_lock(hdev);
2811
2812 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002813 struct inquiry_info_with_rssi_and_pscan_mode *info;
2814 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002815
Johan Hedberge17acd42011-03-30 23:57:16 +03002816 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002817 bacpy(&data.bdaddr, &info->bdaddr);
2818 data.pscan_rep_mode = info->pscan_rep_mode;
2819 data.pscan_period_mode = info->pscan_period_mode;
2820 data.pscan_mode = info->pscan_mode;
2821 memcpy(data.dev_class, info->dev_class, 3);
2822 data.clock_offset = info->clock_offset;
2823 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002824 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002825
2826 name_known = hci_inquiry_cache_update(hdev, &data,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002827 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002828 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002829 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002830 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002831 }
2832 } else {
2833 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2834
Johan Hedberge17acd42011-03-30 23:57:16 +03002835 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002836 bacpy(&data.bdaddr, &info->bdaddr);
2837 data.pscan_rep_mode = info->pscan_rep_mode;
2838 data.pscan_period_mode = info->pscan_period_mode;
2839 data.pscan_mode = 0x00;
2840 memcpy(data.dev_class, info->dev_class, 3);
2841 data.clock_offset = info->clock_offset;
2842 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002843 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002844 name_known = hci_inquiry_cache_update(hdev, &data,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002845 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002846 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002847 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002848 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002849 }
2850 }
2851
2852 hci_dev_unlock(hdev);
2853}
2854
2855static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2856{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002857 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2858 struct hci_conn *conn;
2859
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002860 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002861
Marcel Holtmann41a96212008-07-14 20:13:48 +02002862 hci_dev_lock(hdev);
2863
2864 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002865 if (!conn)
2866 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002867
Johan Hedbergccd556f2010-11-10 17:11:51 +02002868 if (!ev->status && ev->page == 0x01) {
2869 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002870
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002871 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2872 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002873 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002874
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002875 if (ev->features[0] & LMP_HOST_SSP)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002876 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002877 }
2878
Johan Hedbergccd556f2010-11-10 17:11:51 +02002879 if (conn->state != BT_CONFIG)
2880 goto unlock;
2881
Johan Hedberg127178d2010-11-18 22:22:29 +02002882 if (!ev->status) {
2883 struct hci_cp_remote_name_req cp;
2884 memset(&cp, 0, sizeof(cp));
2885 bacpy(&cp.bdaddr, &conn->dst);
2886 cp.pscan_rep_mode = 0x02;
2887 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002888 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2889 mgmt_device_connected(hdev, &conn->dst, conn->type,
Johan Hedberg08c79b62012-02-23 22:31:51 +02002890 conn->dst_type, 0, NULL, 0,
Johan Hedbergb644ba32012-01-17 21:48:47 +02002891 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002892
Johan Hedberg127178d2010-11-18 22:22:29 +02002893 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002894 conn->state = BT_CONNECTED;
2895 hci_proto_connect_cfm(conn, ev->status);
2896 hci_conn_put(conn);
2897 }
2898
2899unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002900 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002901}
2902
2903static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2904{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002905 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2906 struct hci_conn *conn;
2907
2908 BT_DBG("%s status %d", hdev->name, ev->status);
2909
2910 hci_dev_lock(hdev);
2911
2912 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002913 if (!conn) {
2914 if (ev->link_type == ESCO_LINK)
2915 goto unlock;
2916
2917 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2918 if (!conn)
2919 goto unlock;
2920
2921 conn->type = SCO_LINK;
2922 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002923
Marcel Holtmann732547f2009-04-19 19:14:14 +02002924 switch (ev->status) {
2925 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002926 conn->handle = __le16_to_cpu(ev->handle);
2927 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002928
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002929 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002930 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002931 break;
2932
Stephen Coe705e5712010-02-16 11:29:44 -05002933 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002934 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002935 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002936 case 0x1f: /* Unspecified error */
2937 if (conn->out && conn->attempt < 2) {
2938 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2939 (hdev->esco_type & EDR_ESCO_MASK);
2940 hci_setup_sync(conn, conn->link->handle);
2941 goto unlock;
2942 }
2943 /* fall through */
2944
2945 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002946 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002947 break;
2948 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002949
2950 hci_proto_connect_cfm(conn, ev->status);
2951 if (ev->status)
2952 hci_conn_del(conn);
2953
2954unlock:
2955 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002956}
2957
2958static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2959{
2960 BT_DBG("%s", hdev->name);
2961}
2962
Marcel Holtmann04837f62006-07-03 10:02:33 +02002963static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2964{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002965 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002966
2967 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002968}
2969
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002970static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2971{
2972 struct inquiry_data data;
2973 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2974 int num_rsp = *((__u8 *) skb->data);
2975
2976 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2977
2978 if (!num_rsp)
2979 return;
2980
2981 hci_dev_lock(hdev);
2982
Johan Hedberge17acd42011-03-30 23:57:16 +03002983 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002984 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002985
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002986 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002987 data.pscan_rep_mode = info->pscan_rep_mode;
2988 data.pscan_period_mode = info->pscan_period_mode;
2989 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002990 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002991 data.clock_offset = info->clock_offset;
2992 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002993 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002994
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002995 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002996 name_known = eir_has_data_type(info->data,
2997 sizeof(info->data),
2998 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002999 else
3000 name_known = true;
3001
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003002 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
3003 &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003004 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02003005 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003006 !name_known, ssp, info->data,
Andre Guedes7d262f82012-01-10 18:20:49 -03003007 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003008 }
3009
3010 hci_dev_unlock(hdev);
3011}
3012
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003013static inline u8 hci_get_auth_req(struct hci_conn *conn)
3014{
3015 /* If remote requests dedicated bonding follow that lead */
3016 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3017 /* If both remote and local IO capabilities allow MITM
3018 * protection then require it, otherwise don't */
3019 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3020 return 0x02;
3021 else
3022 return 0x03;
3023 }
3024
3025 /* If remote requests no-bonding follow that lead */
3026 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003027 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003028
3029 return conn->auth_type;
3030}
3031
Marcel Holtmann04936842008-07-14 20:13:48 +02003032static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3033{
3034 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3035 struct hci_conn *conn;
3036
3037 BT_DBG("%s", hdev->name);
3038
3039 hci_dev_lock(hdev);
3040
3041 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003042 if (!conn)
3043 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003044
Johan Hedberg03b555e2011-01-04 15:40:05 +02003045 hci_conn_hold(conn);
3046
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003047 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003048 goto unlock;
3049
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003050 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003051 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003052 struct hci_cp_io_capability_reply cp;
3053
3054 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303055 /* Change the IO capability from KeyboardDisplay
3056 * to DisplayYesNo as it is not supported by BT spec. */
3057 cp.capability = (conn->io_capability == 0x04) ?
3058 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003059 conn->auth_type = hci_get_auth_req(conn);
3060 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003061
Johan Hedberg58a681e2012-01-16 06:47:28 +02003062 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003063 hci_find_remote_oob_data(hdev, &conn->dst))
3064 cp.oob_data = 0x01;
3065 else
3066 cp.oob_data = 0x00;
3067
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003068 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3069 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003070 } else {
3071 struct hci_cp_io_capability_neg_reply cp;
3072
3073 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003074 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003075
3076 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3077 sizeof(cp), &cp);
3078 }
3079
3080unlock:
3081 hci_dev_unlock(hdev);
3082}
3083
3084static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3085{
3086 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3087 struct hci_conn *conn;
3088
3089 BT_DBG("%s", hdev->name);
3090
3091 hci_dev_lock(hdev);
3092
3093 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3094 if (!conn)
3095 goto unlock;
3096
Johan Hedberg03b555e2011-01-04 15:40:05 +02003097 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003098 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003099 if (ev->oob_data)
3100 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003101
3102unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003103 hci_dev_unlock(hdev);
3104}
3105
Johan Hedberga5c29682011-02-19 12:05:57 -03003106static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3107 struct sk_buff *skb)
3108{
3109 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003110 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003111 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003112
3113 BT_DBG("%s", hdev->name);
3114
3115 hci_dev_lock(hdev);
3116
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003117 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003118 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003119
Johan Hedberg7a828902011-04-28 11:28:53 -07003120 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3121 if (!conn)
3122 goto unlock;
3123
3124 loc_mitm = (conn->auth_type & 0x01);
3125 rem_mitm = (conn->remote_auth & 0x01);
3126
3127 /* If we require MITM but the remote device can't provide that
3128 * (it has NoInputNoOutput) then reject the confirmation
3129 * request. The only exception is when we're dedicated bonding
3130 * initiators (connect_cfm_cb set) since then we always have the MITM
3131 * bit set. */
3132 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3133 BT_DBG("Rejecting request: remote device can't provide MITM");
3134 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3135 sizeof(ev->bdaddr), &ev->bdaddr);
3136 goto unlock;
3137 }
3138
3139 /* If no side requires MITM protection; auto-accept */
3140 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3141 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003142
3143 /* If we're not the initiators request authorization to
3144 * proceed from user space (mgmt_user_confirm with
3145 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003146 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003147 BT_DBG("Confirming auto-accept as acceptor");
3148 confirm_hint = 1;
3149 goto confirm;
3150 }
3151
Johan Hedberg9f616562011-04-28 11:28:54 -07003152 BT_DBG("Auto-accept of user confirmation with %ums delay",
3153 hdev->auto_accept_delay);
3154
3155 if (hdev->auto_accept_delay > 0) {
3156 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3157 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3158 goto unlock;
3159 }
3160
Johan Hedberg7a828902011-04-28 11:28:53 -07003161 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3162 sizeof(ev->bdaddr), &ev->bdaddr);
3163 goto unlock;
3164 }
3165
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003166confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003167 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003168 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003169
3170unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003171 hci_dev_unlock(hdev);
3172}
3173
Brian Gix1143d452011-11-23 08:28:34 -08003174static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3175 struct sk_buff *skb)
3176{
3177 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3178
3179 BT_DBG("%s", hdev->name);
3180
3181 hci_dev_lock(hdev);
3182
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003183 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003184 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003185
3186 hci_dev_unlock(hdev);
3187}
3188
Marcel Holtmann04936842008-07-14 20:13:48 +02003189static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3190{
3191 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3192 struct hci_conn *conn;
3193
3194 BT_DBG("%s", hdev->name);
3195
3196 hci_dev_lock(hdev);
3197
3198 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003199 if (!conn)
3200 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003201
Johan Hedberg2a611692011-02-19 12:06:00 -03003202 /* To avoid duplicate auth_failed events to user space we check
3203 * the HCI_CONN_AUTH_PEND flag which will be set if we
3204 * initiated the authentication. A traditional auth_complete
3205 * event gets always produced as initiator and is also mapped to
3206 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003207 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003208 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3209 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003210
3211 hci_conn_put(conn);
3212
3213unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003214 hci_dev_unlock(hdev);
3215}
3216
Marcel Holtmann41a96212008-07-14 20:13:48 +02003217static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3218{
3219 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3220 struct inquiry_entry *ie;
3221
3222 BT_DBG("%s", hdev->name);
3223
3224 hci_dev_lock(hdev);
3225
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003226 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3227 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003228 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003229
3230 hci_dev_unlock(hdev);
3231}
3232
Szymon Janc2763eda2011-03-22 13:12:22 +01003233static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3234 struct sk_buff *skb)
3235{
3236 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3237 struct oob_data *data;
3238
3239 BT_DBG("%s", hdev->name);
3240
3241 hci_dev_lock(hdev);
3242
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003243 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003244 goto unlock;
3245
Szymon Janc2763eda2011-03-22 13:12:22 +01003246 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3247 if (data) {
3248 struct hci_cp_remote_oob_data_reply cp;
3249
3250 bacpy(&cp.bdaddr, &ev->bdaddr);
3251 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3252 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3253
3254 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3255 &cp);
3256 } else {
3257 struct hci_cp_remote_oob_data_neg_reply cp;
3258
3259 bacpy(&cp.bdaddr, &ev->bdaddr);
3260 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3261 &cp);
3262 }
3263
Szymon Jance1ba1f12011-04-06 13:01:59 +02003264unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003265 hci_dev_unlock(hdev);
3266}
3267
Ville Tervofcd89c02011-02-10 22:38:47 -03003268static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3269{
3270 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3271 struct hci_conn *conn;
3272
3273 BT_DBG("%s status %d", hdev->name, ev->status);
3274
3275 hci_dev_lock(hdev);
3276
3277 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003278 if (!conn) {
3279 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3280 if (!conn) {
3281 BT_ERR("No memory for new connection");
3282 hci_dev_unlock(hdev);
3283 return;
3284 }
Andre Guedes29b79882011-05-31 14:20:54 -03003285
3286 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003287 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003288
3289 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003290 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3291 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003292 hci_proto_connect_cfm(conn, ev->status);
3293 conn->state = BT_CLOSED;
3294 hci_conn_del(conn);
3295 goto unlock;
3296 }
3297
Johan Hedbergb644ba32012-01-17 21:48:47 +02003298 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3299 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Szymon Janc95b23582012-02-12 13:55:35 +01003300 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003301
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003302 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003303 conn->handle = __le16_to_cpu(ev->handle);
3304 conn->state = BT_CONNECTED;
3305
3306 hci_conn_hold_device(conn);
3307 hci_conn_add_sysfs(conn);
3308
3309 hci_proto_connect_cfm(conn, ev->status);
3310
3311unlock:
3312 hci_dev_unlock(hdev);
3313}
3314
Andre Guedes9aa04c92011-05-26 16:23:51 -03003315static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3316 struct sk_buff *skb)
3317{
Andre Guedese95beb42011-09-26 20:48:35 -03003318 u8 num_reports = skb->data[0];
3319 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003320 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003321
3322 hci_dev_lock(hdev);
3323
Andre Guedese95beb42011-09-26 20:48:35 -03003324 while (num_reports--) {
3325 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003326
Andre Guedes9aa04c92011-05-26 16:23:51 -03003327 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003328
Andre Guedes3c9e9192012-01-10 18:20:50 -03003329 rssi = ev->data[ev->length];
3330 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003331 NULL, rssi, 0, 1, ev->data,
3332 ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003333
Andre Guedese95beb42011-09-26 20:48:35 -03003334 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003335 }
3336
3337 hci_dev_unlock(hdev);
3338}
3339
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003340static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3341 struct sk_buff *skb)
3342{
3343 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3344 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003345 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003346 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003347 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003348
3349 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3350
3351 hci_dev_lock(hdev);
3352
3353 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003354 if (conn == NULL)
3355 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003356
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003357 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3358 if (ltk == NULL)
3359 goto not_found;
3360
3361 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003362 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003363
3364 if (ltk->authenticated)
3365 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003366
3367 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3368
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003369 if (ltk->type & HCI_SMP_STK) {
3370 list_del(&ltk->list);
3371 kfree(ltk);
3372 }
3373
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003374 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003375
3376 return;
3377
3378not_found:
3379 neg.handle = ev->handle;
3380 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3381 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003382}
3383
Ville Tervofcd89c02011-02-10 22:38:47 -03003384static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3385{
3386 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3387
3388 skb_pull(skb, sizeof(*le_ev));
3389
3390 switch (le_ev->subevent) {
3391 case HCI_EV_LE_CONN_COMPLETE:
3392 hci_le_conn_complete_evt(hdev, skb);
3393 break;
3394
Andre Guedes9aa04c92011-05-26 16:23:51 -03003395 case HCI_EV_LE_ADVERTISING_REPORT:
3396 hci_le_adv_report_evt(hdev, skb);
3397 break;
3398
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003399 case HCI_EV_LE_LTK_REQ:
3400 hci_le_ltk_request_evt(hdev, skb);
3401 break;
3402
Ville Tervofcd89c02011-02-10 22:38:47 -03003403 default:
3404 break;
3405 }
3406}
3407
Linus Torvalds1da177e2005-04-16 15:20:36 -07003408void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3409{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003410 struct hci_event_hdr *hdr = (void *) skb->data;
3411 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003412
3413 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3414
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003415 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003416 case HCI_EV_INQUIRY_COMPLETE:
3417 hci_inquiry_complete_evt(hdev, skb);
3418 break;
3419
3420 case HCI_EV_INQUIRY_RESULT:
3421 hci_inquiry_result_evt(hdev, skb);
3422 break;
3423
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003424 case HCI_EV_CONN_COMPLETE:
3425 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003426 break;
3427
Linus Torvalds1da177e2005-04-16 15:20:36 -07003428 case HCI_EV_CONN_REQUEST:
3429 hci_conn_request_evt(hdev, skb);
3430 break;
3431
Linus Torvalds1da177e2005-04-16 15:20:36 -07003432 case HCI_EV_DISCONN_COMPLETE:
3433 hci_disconn_complete_evt(hdev, skb);
3434 break;
3435
Linus Torvalds1da177e2005-04-16 15:20:36 -07003436 case HCI_EV_AUTH_COMPLETE:
3437 hci_auth_complete_evt(hdev, skb);
3438 break;
3439
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003440 case HCI_EV_REMOTE_NAME:
3441 hci_remote_name_evt(hdev, skb);
3442 break;
3443
Linus Torvalds1da177e2005-04-16 15:20:36 -07003444 case HCI_EV_ENCRYPT_CHANGE:
3445 hci_encrypt_change_evt(hdev, skb);
3446 break;
3447
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003448 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3449 hci_change_link_key_complete_evt(hdev, skb);
3450 break;
3451
3452 case HCI_EV_REMOTE_FEATURES:
3453 hci_remote_features_evt(hdev, skb);
3454 break;
3455
3456 case HCI_EV_REMOTE_VERSION:
3457 hci_remote_version_evt(hdev, skb);
3458 break;
3459
3460 case HCI_EV_QOS_SETUP_COMPLETE:
3461 hci_qos_setup_complete_evt(hdev, skb);
3462 break;
3463
3464 case HCI_EV_CMD_COMPLETE:
3465 hci_cmd_complete_evt(hdev, skb);
3466 break;
3467
3468 case HCI_EV_CMD_STATUS:
3469 hci_cmd_status_evt(hdev, skb);
3470 break;
3471
3472 case HCI_EV_ROLE_CHANGE:
3473 hci_role_change_evt(hdev, skb);
3474 break;
3475
3476 case HCI_EV_NUM_COMP_PKTS:
3477 hci_num_comp_pkts_evt(hdev, skb);
3478 break;
3479
3480 case HCI_EV_MODE_CHANGE:
3481 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003482 break;
3483
3484 case HCI_EV_PIN_CODE_REQ:
3485 hci_pin_code_request_evt(hdev, skb);
3486 break;
3487
3488 case HCI_EV_LINK_KEY_REQ:
3489 hci_link_key_request_evt(hdev, skb);
3490 break;
3491
3492 case HCI_EV_LINK_KEY_NOTIFY:
3493 hci_link_key_notify_evt(hdev, skb);
3494 break;
3495
3496 case HCI_EV_CLOCK_OFFSET:
3497 hci_clock_offset_evt(hdev, skb);
3498 break;
3499
Marcel Holtmanna8746412008-07-14 20:13:46 +02003500 case HCI_EV_PKT_TYPE_CHANGE:
3501 hci_pkt_type_change_evt(hdev, skb);
3502 break;
3503
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003504 case HCI_EV_PSCAN_REP_MODE:
3505 hci_pscan_rep_mode_evt(hdev, skb);
3506 break;
3507
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003508 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3509 hci_inquiry_result_with_rssi_evt(hdev, skb);
3510 break;
3511
3512 case HCI_EV_REMOTE_EXT_FEATURES:
3513 hci_remote_ext_features_evt(hdev, skb);
3514 break;
3515
3516 case HCI_EV_SYNC_CONN_COMPLETE:
3517 hci_sync_conn_complete_evt(hdev, skb);
3518 break;
3519
3520 case HCI_EV_SYNC_CONN_CHANGED:
3521 hci_sync_conn_changed_evt(hdev, skb);
3522 break;
3523
Marcel Holtmann04837f62006-07-03 10:02:33 +02003524 case HCI_EV_SNIFF_SUBRATE:
3525 hci_sniff_subrate_evt(hdev, skb);
3526 break;
3527
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003528 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3529 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003530 break;
3531
Marcel Holtmann04936842008-07-14 20:13:48 +02003532 case HCI_EV_IO_CAPA_REQUEST:
3533 hci_io_capa_request_evt(hdev, skb);
3534 break;
3535
Johan Hedberg03b555e2011-01-04 15:40:05 +02003536 case HCI_EV_IO_CAPA_REPLY:
3537 hci_io_capa_reply_evt(hdev, skb);
3538 break;
3539
Johan Hedberga5c29682011-02-19 12:05:57 -03003540 case HCI_EV_USER_CONFIRM_REQUEST:
3541 hci_user_confirm_request_evt(hdev, skb);
3542 break;
3543
Brian Gix1143d452011-11-23 08:28:34 -08003544 case HCI_EV_USER_PASSKEY_REQUEST:
3545 hci_user_passkey_request_evt(hdev, skb);
3546 break;
3547
Marcel Holtmann04936842008-07-14 20:13:48 +02003548 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3549 hci_simple_pair_complete_evt(hdev, skb);
3550 break;
3551
Marcel Holtmann41a96212008-07-14 20:13:48 +02003552 case HCI_EV_REMOTE_HOST_FEATURES:
3553 hci_remote_host_features_evt(hdev, skb);
3554 break;
3555
Ville Tervofcd89c02011-02-10 22:38:47 -03003556 case HCI_EV_LE_META:
3557 hci_le_meta_evt(hdev, skb);
3558 break;
3559
Szymon Janc2763eda2011-03-22 13:12:22 +01003560 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3561 hci_remote_oob_data_request_evt(hdev, skb);
3562 break;
3563
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003564 case HCI_EV_NUM_COMP_BLOCKS:
3565 hci_num_comp_blocks_evt(hdev, skb);
3566 break;
3567
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003568 default:
3569 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003570 break;
3571 }
3572
3573 kfree_skb(skb);
3574 hdev->stat.evt_rx++;
3575}