blob: 6a72eaea70ee62b615344013ae5c9f9bd2e9e324 [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 */
Johan Hedberg9f8ce962012-03-02 03:06:04 +0200196 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN) | BIT(HCI_PENDING_CLASS));
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 Emeltchenkoe61ef492011-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 Hedberg54d04db2012-02-22 15:47:48 +0200555 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
556 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
557 u8 mode = 0x01;
558 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300559 sizeof(mode), &mode);
Johan Hedberg54d04db2012-02-22 15:47:48 +0200560 } else {
561 struct hci_cp_write_eir cp;
562
563 memset(hdev->eir, 0, sizeof(hdev->eir));
564 memset(&cp, 0, sizeof(cp));
565
566 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
567 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200568 }
569
570 if (hdev->features[3] & LMP_RSSI_INQ)
571 hci_setup_inquiry_mode(hdev);
572
573 if (hdev->features[7] & LMP_INQ_TX_PWR)
574 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300575
576 if (hdev->features[7] & LMP_EXTFEATURES) {
577 struct hci_cp_read_local_ext_features cp;
578
579 cp.page = 0x01;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300580 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp),
581 &cp);
Andre Guedes971e3a42011-06-30 19:20:52 -0300582 }
Andre Guedese6100a22011-06-30 19:20:54 -0300583
Johan Hedberg47990ea2012-02-22 11:58:37 +0200584 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
585 u8 enable = 1;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300586 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
587 &enable);
Johan Hedberg47990ea2012-02-22 11:58:37 +0200588 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200589}
590
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200591static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
592{
593 struct hci_rp_read_local_version *rp = (void *) skb->data;
594
595 BT_DBG("%s status 0x%x", hdev->name, rp->status);
596
597 if (rp->status)
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200598 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200599
600 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200601 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200602 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200603 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200604 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200605
606 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
607 hdev->manufacturer,
608 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200609
610 if (test_bit(HCI_INIT, &hdev->flags))
611 hci_setup(hdev);
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200612
613done:
614 hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200615}
616
617static void hci_setup_link_policy(struct hci_dev *hdev)
618{
619 u16 link_policy = 0;
620
621 if (hdev->features[0] & LMP_RSWITCH)
622 link_policy |= HCI_LP_RSWITCH;
623 if (hdev->features[0] & LMP_HOLD)
624 link_policy |= HCI_LP_HOLD;
625 if (hdev->features[0] & LMP_SNIFF)
626 link_policy |= HCI_LP_SNIFF;
627 if (hdev->features[1] & LMP_PARK)
628 link_policy |= HCI_LP_PARK;
629
630 link_policy = cpu_to_le16(link_policy);
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300631 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(link_policy),
632 &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200633}
634
635static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
636{
637 struct hci_rp_read_local_commands *rp = (void *) skb->data;
638
639 BT_DBG("%s status 0x%x", hdev->name, rp->status);
640
641 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200642 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200643
644 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200645
646 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
647 hci_setup_link_policy(hdev);
648
649done:
650 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200651}
652
653static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
654{
655 struct hci_rp_read_local_features *rp = (void *) skb->data;
656
657 BT_DBG("%s status 0x%x", hdev->name, rp->status);
658
659 if (rp->status)
660 return;
661
662 memcpy(hdev->features, rp->features, 8);
663
664 /* Adjust default settings according to features
665 * supported by device. */
666
667 if (hdev->features[0] & LMP_3SLOT)
668 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
669
670 if (hdev->features[0] & LMP_5SLOT)
671 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
672
673 if (hdev->features[1] & LMP_HV2) {
674 hdev->pkt_type |= (HCI_HV2);
675 hdev->esco_type |= (ESCO_HV2);
676 }
677
678 if (hdev->features[1] & LMP_HV3) {
679 hdev->pkt_type |= (HCI_HV3);
680 hdev->esco_type |= (ESCO_HV3);
681 }
682
683 if (hdev->features[3] & LMP_ESCO)
684 hdev->esco_type |= (ESCO_EV3);
685
686 if (hdev->features[4] & LMP_EV4)
687 hdev->esco_type |= (ESCO_EV4);
688
689 if (hdev->features[4] & LMP_EV5)
690 hdev->esco_type |= (ESCO_EV5);
691
Marcel Holtmannefc76882009-02-06 09:13:37 +0100692 if (hdev->features[5] & LMP_EDR_ESCO_2M)
693 hdev->esco_type |= (ESCO_2EV3);
694
695 if (hdev->features[5] & LMP_EDR_ESCO_3M)
696 hdev->esco_type |= (ESCO_3EV3);
697
698 if (hdev->features[5] & LMP_EDR_3S_ESCO)
699 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
700
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200701 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
702 hdev->features[0], hdev->features[1],
703 hdev->features[2], hdev->features[3],
704 hdev->features[4], hdev->features[5],
705 hdev->features[6], hdev->features[7]);
706}
707
Johan Hedberg8f984df2012-02-28 01:07:22 +0200708static void hci_set_le_support(struct hci_dev *hdev)
709{
710 struct hci_cp_write_le_host_supported cp;
711
712 memset(&cp, 0, sizeof(cp));
713
714 if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
715 cp.le = 1;
716 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
717 }
718
719 if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300720 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
721 &cp);
Johan Hedberg8f984df2012-02-28 01:07:22 +0200722}
723
Andre Guedes971e3a42011-06-30 19:20:52 -0300724static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
725 struct sk_buff *skb)
726{
727 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
728
729 BT_DBG("%s status 0x%x", hdev->name, rp->status);
730
731 if (rp->status)
Johan Hedberg8f984df2012-02-28 01:07:22 +0200732 goto done;
Andre Guedes971e3a42011-06-30 19:20:52 -0300733
Andre Guedesb5b32b62011-12-30 10:34:04 -0300734 switch (rp->page) {
735 case 0:
736 memcpy(hdev->features, rp->features, 8);
737 break;
738 case 1:
739 memcpy(hdev->host_features, rp->features, 8);
740 break;
741 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300742
Johan Hedberg8f984df2012-02-28 01:07:22 +0200743 if (test_bit(HCI_INIT, &hdev->flags) && hdev->features[4] & LMP_LE)
744 hci_set_le_support(hdev);
745
746done:
Andre Guedes971e3a42011-06-30 19:20:52 -0300747 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
748}
749
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200750static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
751 struct sk_buff *skb)
752{
753 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
754
755 BT_DBG("%s status 0x%x", hdev->name, rp->status);
756
757 if (rp->status)
758 return;
759
760 hdev->flow_ctl_mode = rp->mode;
761
762 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
763}
764
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200765static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
766{
767 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
768
769 BT_DBG("%s status 0x%x", hdev->name, rp->status);
770
771 if (rp->status)
772 return;
773
774 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
775 hdev->sco_mtu = rp->sco_mtu;
776 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
777 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
778
779 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
780 hdev->sco_mtu = 64;
781 hdev->sco_pkts = 8;
782 }
783
784 hdev->acl_cnt = hdev->acl_pkts;
785 hdev->sco_cnt = hdev->sco_pkts;
786
787 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
788 hdev->acl_mtu, hdev->acl_pkts,
789 hdev->sco_mtu, hdev->sco_pkts);
790}
791
792static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
793{
794 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
795
796 BT_DBG("%s status 0x%x", hdev->name, rp->status);
797
798 if (!rp->status)
799 bacpy(&hdev->bdaddr, &rp->bdaddr);
800
Johan Hedberg23bb5762010-12-21 23:01:27 +0200801 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
802}
803
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200804static void hci_cc_read_data_block_size(struct hci_dev *hdev,
805 struct sk_buff *skb)
806{
807 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
808
809 BT_DBG("%s status 0x%x", hdev->name, rp->status);
810
811 if (rp->status)
812 return;
813
814 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
815 hdev->block_len = __le16_to_cpu(rp->block_len);
816 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
817
818 hdev->block_cnt = hdev->num_blocks;
819
820 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
821 hdev->block_cnt, hdev->block_len);
822
823 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
824}
825
Johan Hedberg23bb5762010-12-21 23:01:27 +0200826static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
827{
828 __u8 status = *((__u8 *) skb->data);
829
830 BT_DBG("%s status 0x%x", hdev->name, status);
831
832 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200833}
834
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300835static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
836 struct sk_buff *skb)
837{
838 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
839
840 BT_DBG("%s status 0x%x", hdev->name, rp->status);
841
842 if (rp->status)
843 return;
844
845 hdev->amp_status = rp->amp_status;
846 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
847 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
848 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
849 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
850 hdev->amp_type = rp->amp_type;
851 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
852 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
853 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
854 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
855
856 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
857}
858
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200859static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
860 struct sk_buff *skb)
861{
862 __u8 status = *((__u8 *) skb->data);
863
864 BT_DBG("%s status 0x%x", hdev->name, status);
865
866 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
867}
868
Johan Hedbergd5859e22011-01-25 01:19:58 +0200869static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
870{
871 __u8 status = *((__u8 *) skb->data);
872
873 BT_DBG("%s status 0x%x", hdev->name, status);
874
875 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
876}
877
878static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
879 struct sk_buff *skb)
880{
881 __u8 status = *((__u8 *) skb->data);
882
883 BT_DBG("%s status 0x%x", hdev->name, status);
884
885 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
886}
887
888static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
889 struct sk_buff *skb)
890{
891 __u8 status = *((__u8 *) skb->data);
892
893 BT_DBG("%s status 0x%x", hdev->name, status);
894
895 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
896}
897
898static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
899{
900 __u8 status = *((__u8 *) skb->data);
901
902 BT_DBG("%s status 0x%x", hdev->name, status);
903
904 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
905}
906
Johan Hedberg980e1a52011-01-22 06:10:07 +0200907static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
908{
909 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
910 struct hci_cp_pin_code_reply *cp;
911 struct hci_conn *conn;
912
913 BT_DBG("%s status 0x%x", hdev->name, rp->status);
914
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200915 hci_dev_lock(hdev);
916
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200917 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200918 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200919
920 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200921 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200922
923 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
924 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200925 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200926
927 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
928 if (conn)
929 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200930
931unlock:
932 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200933}
934
935static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
936{
937 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
938
939 BT_DBG("%s status 0x%x", hdev->name, rp->status);
940
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200941 hci_dev_lock(hdev);
942
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200943 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200944 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200945 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200946
947 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200948}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200949
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300950static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
951 struct sk_buff *skb)
952{
953 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
954
955 BT_DBG("%s status 0x%x", hdev->name, rp->status);
956
957 if (rp->status)
958 return;
959
960 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
961 hdev->le_pkts = rp->le_max_pkt;
962
963 hdev->le_cnt = hdev->le_pkts;
964
965 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
966
967 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
968}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200969
Johan Hedberga5c29682011-02-19 12:05:57 -0300970static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
971{
972 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
973
974 BT_DBG("%s status 0x%x", hdev->name, rp->status);
975
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200976 hci_dev_lock(hdev);
977
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200978 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300979 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
980 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200981
982 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300983}
984
985static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
986 struct sk_buff *skb)
987{
988 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
989
990 BT_DBG("%s status 0x%x", hdev->name, rp->status);
991
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200992 hci_dev_lock(hdev);
993
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200994 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200995 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300996 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200997
998 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300999}
1000
Brian Gix1143d452011-11-23 08:28:34 -08001001static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
1002{
1003 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1004
1005 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1006
1007 hci_dev_lock(hdev);
1008
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001009 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001010 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001011 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001012
1013 hci_dev_unlock(hdev);
1014}
1015
1016static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1017 struct sk_buff *skb)
1018{
1019 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1020
1021 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1022
1023 hci_dev_lock(hdev);
1024
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001025 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001026 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001027 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001028
1029 hci_dev_unlock(hdev);
1030}
1031
Szymon Jancc35938b2011-03-22 13:12:21 +01001032static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1033 struct sk_buff *skb)
1034{
1035 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1036
1037 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1038
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001039 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001040 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001041 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001042 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001043}
1044
Andre Guedes07f7fa52011-12-02 21:13:31 +09001045static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1046{
1047 __u8 status = *((__u8 *) skb->data);
1048
1049 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001050
1051 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001052
1053 if (status) {
1054 hci_dev_lock(hdev);
1055 mgmt_start_discovery_failed(hdev, status);
1056 hci_dev_unlock(hdev);
1057 return;
1058 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001059}
1060
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001061static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1062 struct sk_buff *skb)
1063{
1064 struct hci_cp_le_set_scan_enable *cp;
1065 __u8 status = *((__u8 *) skb->data);
1066
1067 BT_DBG("%s status 0x%x", hdev->name, status);
1068
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001069 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1070 if (!cp)
1071 return;
1072
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001073 switch (cp->enable) {
1074 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001075 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1076
Andre Guedes3fd24152012-02-03 17:48:01 -03001077 if (status) {
1078 hci_dev_lock(hdev);
1079 mgmt_start_discovery_failed(hdev, status);
1080 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001081 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001082 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001083
Andre Guedesd23264a2011-11-25 20:53:38 -03001084 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1085
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001086 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001087
1088 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001089 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001090 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001091 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001092 break;
1093
1094 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001095 if (status)
1096 return;
1097
Andre Guedesd23264a2011-11-25 20:53:38 -03001098 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1099
Andre Guedesd0843292012-01-02 19:18:11 -03001100 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001101
1102 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1103 mgmt_interleaved_discovery(hdev);
1104 } else {
1105 hci_dev_lock(hdev);
1106 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1107 hci_dev_unlock(hdev);
1108 }
1109
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001110 break;
1111
1112 default:
1113 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1114 break;
Andre Guedes35815082011-05-26 16:23:53 -03001115 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001116}
1117
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001118static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1119{
1120 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1121
1122 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1123
1124 if (rp->status)
1125 return;
1126
1127 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1128}
1129
1130static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1131{
1132 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1133
1134 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1135
1136 if (rp->status)
1137 return;
1138
1139 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1140}
1141
Andre Guedesf9b49302011-06-30 19:20:53 -03001142static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1143 struct sk_buff *skb)
1144{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001145 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001146 __u8 status = *((__u8 *) skb->data);
1147
1148 BT_DBG("%s status 0x%x", hdev->name, status);
1149
Johan Hedberg06199cf2012-02-22 16:37:11 +02001150 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001151 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001152 return;
1153
Johan Hedberg8f984df2012-02-28 01:07:22 +02001154 if (!status) {
1155 if (sent->le)
1156 hdev->host_features[0] |= LMP_HOST_LE;
1157 else
1158 hdev->host_features[0] &= ~LMP_HOST_LE;
1159 }
1160
1161 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
1162 !test_bit(HCI_INIT, &hdev->flags))
1163 mgmt_le_enable_complete(hdev, sent->le, status);
1164
1165 hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001166}
1167
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001168static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1169{
1170 BT_DBG("%s status 0x%x", hdev->name, status);
1171
1172 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001173 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001174 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001175 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001176 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001177 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001178 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001179 return;
1180 }
1181
Andre Guedes89352e72011-11-04 14:16:53 -03001182 set_bit(HCI_INQUIRY, &hdev->flags);
1183
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001184 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001185 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001186 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001187}
1188
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1190{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001191 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001194 BT_DBG("%s status 0x%x", hdev->name, status);
1195
1196 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 if (!cp)
1198 return;
1199
1200 hci_dev_lock(hdev);
1201
1202 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1203
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001204 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205
1206 if (status) {
1207 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001208 if (status != 0x0c || conn->attempt > 2) {
1209 conn->state = BT_CLOSED;
1210 hci_proto_connect_cfm(conn, status);
1211 hci_conn_del(conn);
1212 } else
1213 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 }
1215 } else {
1216 if (!conn) {
1217 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1218 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001219 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 conn->link_mode |= HCI_LM_MASTER;
1221 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001222 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 }
1224 }
1225
1226 hci_dev_unlock(hdev);
1227}
1228
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001229static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001231 struct hci_cp_add_sco *cp;
1232 struct hci_conn *acl, *sco;
1233 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001235 BT_DBG("%s status 0x%x", hdev->name, status);
1236
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001237 if (!status)
1238 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001240 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1241 if (!cp)
1242 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001244 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001246 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001247
1248 hci_dev_lock(hdev);
1249
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001250 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001251 if (acl) {
1252 sco = acl->link;
1253 if (sco) {
1254 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001255
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001256 hci_proto_connect_cfm(sco, status);
1257 hci_conn_del(sco);
1258 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001259 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001260
1261 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262}
1263
Marcel Holtmannf8558552008-07-14 20:13:49 +02001264static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1265{
1266 struct hci_cp_auth_requested *cp;
1267 struct hci_conn *conn;
1268
1269 BT_DBG("%s status 0x%x", hdev->name, status);
1270
1271 if (!status)
1272 return;
1273
1274 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1275 if (!cp)
1276 return;
1277
1278 hci_dev_lock(hdev);
1279
1280 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1281 if (conn) {
1282 if (conn->state == BT_CONFIG) {
1283 hci_proto_connect_cfm(conn, status);
1284 hci_conn_put(conn);
1285 }
1286 }
1287
1288 hci_dev_unlock(hdev);
1289}
1290
1291static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1292{
1293 struct hci_cp_set_conn_encrypt *cp;
1294 struct hci_conn *conn;
1295
1296 BT_DBG("%s status 0x%x", hdev->name, status);
1297
1298 if (!status)
1299 return;
1300
1301 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1302 if (!cp)
1303 return;
1304
1305 hci_dev_lock(hdev);
1306
1307 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1308 if (conn) {
1309 if (conn->state == BT_CONFIG) {
1310 hci_proto_connect_cfm(conn, status);
1311 hci_conn_put(conn);
1312 }
1313 }
1314
1315 hci_dev_unlock(hdev);
1316}
1317
Johan Hedberg127178d2010-11-18 22:22:29 +02001318static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001319 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001320{
Johan Hedberg392599b2010-11-18 22:22:28 +02001321 if (conn->state != BT_CONFIG || !conn->out)
1322 return 0;
1323
Johan Hedberg765c2a92011-01-19 12:06:52 +05301324 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001325 return 0;
1326
1327 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001328 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001329 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001330 conn->pending_sec_level != BT_SECURITY_HIGH &&
1331 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001332 return 0;
1333
Johan Hedberg392599b2010-11-18 22:22:28 +02001334 return 1;
1335}
1336
Gustavo F. Padovan00abfe42012-03-01 00:37:10 -03001337static inline int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001338 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001339{
1340 struct hci_cp_remote_name_req cp;
1341
1342 memset(&cp, 0, sizeof(cp));
1343
1344 bacpy(&cp.bdaddr, &e->data.bdaddr);
1345 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1346 cp.pscan_mode = e->data.pscan_mode;
1347 cp.clock_offset = e->data.clock_offset;
1348
1349 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1350}
1351
Johan Hedbergb644ba32012-01-17 21:48:47 +02001352static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001353{
1354 struct discovery_state *discov = &hdev->discovery;
1355 struct inquiry_entry *e;
1356
Johan Hedbergb644ba32012-01-17 21:48:47 +02001357 if (list_empty(&discov->resolve))
1358 return false;
1359
1360 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1361 if (hci_resolve_name(hdev, e) == 0) {
1362 e->name_state = NAME_PENDING;
1363 return true;
1364 }
1365
1366 return false;
1367}
1368
1369static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001370 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001371{
1372 struct discovery_state *discov = &hdev->discovery;
1373 struct inquiry_entry *e;
1374
1375 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001376 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1377 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001378
1379 if (discov->state == DISCOVERY_STOPPED)
1380 return;
1381
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001382 if (discov->state == DISCOVERY_STOPPING)
1383 goto discov_complete;
1384
1385 if (discov->state != DISCOVERY_RESOLVING)
1386 return;
1387
1388 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1389 if (e) {
1390 e->name_state = NAME_KNOWN;
1391 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001392 if (name)
1393 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001394 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001395 }
1396
Johan Hedbergb644ba32012-01-17 21:48:47 +02001397 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001398 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001399
1400discov_complete:
1401 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1402}
1403
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001404static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1405{
Johan Hedberg127178d2010-11-18 22:22:29 +02001406 struct hci_cp_remote_name_req *cp;
1407 struct hci_conn *conn;
1408
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001409 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001410
1411 /* If successful wait for the name req complete event before
1412 * checking for the need to do authentication */
1413 if (!status)
1414 return;
1415
1416 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1417 if (!cp)
1418 return;
1419
1420 hci_dev_lock(hdev);
1421
1422 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001423
1424 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1425 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1426
Johan Hedberg79c6c702011-04-28 11:28:55 -07001427 if (!conn)
1428 goto unlock;
1429
1430 if (!hci_outgoing_auth_needed(hdev, conn))
1431 goto unlock;
1432
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001433 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001434 struct hci_cp_auth_requested cp;
1435 cp.handle = __cpu_to_le16(conn->handle);
1436 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1437 }
1438
Johan Hedberg79c6c702011-04-28 11:28:55 -07001439unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001440 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001441}
1442
Marcel Holtmann769be972008-07-14 20:13:49 +02001443static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1444{
1445 struct hci_cp_read_remote_features *cp;
1446 struct hci_conn *conn;
1447
1448 BT_DBG("%s status 0x%x", hdev->name, status);
1449
1450 if (!status)
1451 return;
1452
1453 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1454 if (!cp)
1455 return;
1456
1457 hci_dev_lock(hdev);
1458
1459 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1460 if (conn) {
1461 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001462 hci_proto_connect_cfm(conn, status);
1463 hci_conn_put(conn);
1464 }
1465 }
1466
1467 hci_dev_unlock(hdev);
1468}
1469
1470static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1471{
1472 struct hci_cp_read_remote_ext_features *cp;
1473 struct hci_conn *conn;
1474
1475 BT_DBG("%s status 0x%x", hdev->name, status);
1476
1477 if (!status)
1478 return;
1479
1480 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1481 if (!cp)
1482 return;
1483
1484 hci_dev_lock(hdev);
1485
1486 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1487 if (conn) {
1488 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001489 hci_proto_connect_cfm(conn, status);
1490 hci_conn_put(conn);
1491 }
1492 }
1493
1494 hci_dev_unlock(hdev);
1495}
1496
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001497static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1498{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001499 struct hci_cp_setup_sync_conn *cp;
1500 struct hci_conn *acl, *sco;
1501 __u16 handle;
1502
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001503 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001504
1505 if (!status)
1506 return;
1507
1508 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1509 if (!cp)
1510 return;
1511
1512 handle = __le16_to_cpu(cp->handle);
1513
1514 BT_DBG("%s handle %d", hdev->name, handle);
1515
1516 hci_dev_lock(hdev);
1517
1518 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001519 if (acl) {
1520 sco = acl->link;
1521 if (sco) {
1522 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001523
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001524 hci_proto_connect_cfm(sco, status);
1525 hci_conn_del(sco);
1526 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001527 }
1528
1529 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001530}
1531
1532static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1533{
1534 struct hci_cp_sniff_mode *cp;
1535 struct hci_conn *conn;
1536
1537 BT_DBG("%s status 0x%x", hdev->name, status);
1538
1539 if (!status)
1540 return;
1541
1542 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1543 if (!cp)
1544 return;
1545
1546 hci_dev_lock(hdev);
1547
1548 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001549 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001550 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001551
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001552 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001553 hci_sco_setup(conn, status);
1554 }
1555
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001556 hci_dev_unlock(hdev);
1557}
1558
1559static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1560{
1561 struct hci_cp_exit_sniff_mode *cp;
1562 struct hci_conn *conn;
1563
1564 BT_DBG("%s status 0x%x", hdev->name, status);
1565
1566 if (!status)
1567 return;
1568
1569 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1570 if (!cp)
1571 return;
1572
1573 hci_dev_lock(hdev);
1574
1575 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001576 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001577 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001578
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001579 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001580 hci_sco_setup(conn, status);
1581 }
1582
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001583 hci_dev_unlock(hdev);
1584}
1585
Johan Hedberg88c3df12012-02-09 14:27:38 +02001586static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1587{
1588 struct hci_cp_disconnect *cp;
1589 struct hci_conn *conn;
1590
1591 if (!status)
1592 return;
1593
1594 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1595 if (!cp)
1596 return;
1597
1598 hci_dev_lock(hdev);
1599
1600 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1601 if (conn)
1602 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001603 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001604
1605 hci_dev_unlock(hdev);
1606}
1607
Ville Tervofcd89c02011-02-10 22:38:47 -03001608static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1609{
1610 struct hci_cp_le_create_conn *cp;
1611 struct hci_conn *conn;
1612
1613 BT_DBG("%s status 0x%x", hdev->name, status);
1614
1615 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1616 if (!cp)
1617 return;
1618
1619 hci_dev_lock(hdev);
1620
1621 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1622
1623 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1624 conn);
1625
1626 if (status) {
1627 if (conn && conn->state == BT_CONNECT) {
1628 conn->state = BT_CLOSED;
1629 hci_proto_connect_cfm(conn, status);
1630 hci_conn_del(conn);
1631 }
1632 } else {
1633 if (!conn) {
1634 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001635 if (conn) {
1636 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001637 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001638 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001639 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001640 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001641 }
1642 }
1643
1644 hci_dev_unlock(hdev);
1645}
1646
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001647static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1648{
1649 BT_DBG("%s status 0x%x", hdev->name, status);
1650}
1651
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001652static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1653{
1654 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001655 struct discovery_state *discov = &hdev->discovery;
1656 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001657
1658 BT_DBG("%s status %d", hdev->name, status);
1659
Johan Hedberg23bb5762010-12-21 23:01:27 +02001660 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001661
1662 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001663
1664 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1665 return;
1666
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001667 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001668 return;
1669
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001670 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001671
Andre Guedes343f9352012-02-17 20:39:37 -03001672 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001673 goto unlock;
1674
1675 if (list_empty(&discov->resolve)) {
1676 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1677 goto unlock;
1678 }
1679
1680 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1681 if (e && hci_resolve_name(hdev, e) == 0) {
1682 e->name_state = NAME_PENDING;
1683 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1684 } else {
1685 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1686 }
1687
1688unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001689 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001690}
1691
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1693{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001694 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001695 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 int num_rsp = *((__u8 *) skb->data);
1697
1698 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1699
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001700 if (!num_rsp)
1701 return;
1702
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001704
Johan Hedberge17acd42011-03-30 23:57:16 +03001705 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001706 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001707
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 bacpy(&data.bdaddr, &info->bdaddr);
1709 data.pscan_rep_mode = info->pscan_rep_mode;
1710 data.pscan_period_mode = info->pscan_period_mode;
1711 data.pscan_mode = info->pscan_mode;
1712 memcpy(data.dev_class, info->dev_class, 3);
1713 data.clock_offset = info->clock_offset;
1714 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001715 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001716
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001717 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001718 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001719 info->dev_class, 0, !name_known, ssp, NULL,
1720 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001722
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 hci_dev_unlock(hdev);
1724}
1725
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001726static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001728 struct hci_ev_conn_complete *ev = (void *) skb->data;
1729 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001731 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001732
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001734
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001735 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001736 if (!conn) {
1737 if (ev->link_type != SCO_LINK)
1738 goto unlock;
1739
1740 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1741 if (!conn)
1742 goto unlock;
1743
1744 conn->type = SCO_LINK;
1745 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001746
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001747 if (!ev->status) {
1748 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001749
1750 if (conn->type == ACL_LINK) {
1751 conn->state = BT_CONFIG;
1752 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001753 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001754 } else
1755 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001756
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001757 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001758 hci_conn_add_sysfs(conn);
1759
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001760 if (test_bit(HCI_AUTH, &hdev->flags))
1761 conn->link_mode |= HCI_LM_AUTH;
1762
1763 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1764 conn->link_mode |= HCI_LM_ENCRYPT;
1765
1766 /* Get remote features */
1767 if (conn->type == ACL_LINK) {
1768 struct hci_cp_read_remote_features cp;
1769 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001770 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001771 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001772 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001773
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001774 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001775 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001776 struct hci_cp_change_conn_ptype cp;
1777 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001778 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001779 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1780 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001781 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001782 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001783 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001784 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001785 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001786 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001787 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001788
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001789 if (conn->type == ACL_LINK)
1790 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001791
Marcel Holtmann769be972008-07-14 20:13:49 +02001792 if (ev->status) {
1793 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001794 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001795 } else if (ev->link_type != ACL_LINK)
1796 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001797
1798unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001800
1801 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802}
1803
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1805{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001806 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 int mask = hdev->link_mode;
1808
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001809 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1810 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811
1812 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1813
Szymon Janc138d22e2011-02-17 16:44:23 +01001814 if ((mask & HCI_LM_ACCEPT) &&
1815 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001817 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819
1820 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001821
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001822 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1823 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001824 memcpy(ie->data.dev_class, ev->dev_class, 3);
1825
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1827 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001828 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1829 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001830 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 hci_dev_unlock(hdev);
1832 return;
1833 }
1834 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001835
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 memcpy(conn->dev_class, ev->dev_class, 3);
1837 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001838
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839 hci_dev_unlock(hdev);
1840
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001841 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1842 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001844 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001846 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1847 cp.role = 0x00; /* Become master */
1848 else
1849 cp.role = 0x01; /* Remain slave */
1850
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001851 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1852 &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001853 } else {
1854 struct hci_cp_accept_sync_conn_req cp;
1855
1856 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001857 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001858
1859 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1860 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1861 cp.max_latency = cpu_to_le16(0xffff);
1862 cp.content_format = cpu_to_le16(hdev->voice_setting);
1863 cp.retrans_effort = 0xff;
1864
1865 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001866 sizeof(cp), &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001867 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 } else {
1869 /* Connection rejected */
1870 struct hci_cp_reject_conn_req cp;
1871
1872 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001873 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001874 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875 }
1876}
1877
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1879{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001880 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001881 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882
1883 BT_DBG("%s status %d", hdev->name, ev->status);
1884
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 hci_dev_lock(hdev);
1886
Marcel Holtmann04837f62006-07-03 10:02:33 +02001887 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001888 if (!conn)
1889 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001890
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001891 if (ev->status == 0)
1892 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893
Johan Hedbergb644ba32012-01-17 21:48:47 +02001894 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1895 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001896 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001897 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1898 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001899 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001900 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001901 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001902 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001903
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001904 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301905 if (conn->type == ACL_LINK && conn->flush_key)
1906 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001907 hci_proto_disconn_cfm(conn, ev->reason);
1908 hci_conn_del(conn);
1909 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001910
1911unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 hci_dev_unlock(hdev);
1913}
1914
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001915static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1916{
1917 struct hci_ev_auth_complete *ev = (void *) skb->data;
1918 struct hci_conn *conn;
1919
1920 BT_DBG("%s status %d", hdev->name, ev->status);
1921
1922 hci_dev_lock(hdev);
1923
1924 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001925 if (!conn)
1926 goto unlock;
1927
1928 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001929 if (!hci_conn_ssp_enabled(conn) &&
1930 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001931 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001932 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001933 conn->link_mode |= HCI_LM_AUTH;
1934 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001935 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001936 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001937 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001938 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001939 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001940
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001941 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1942 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001943
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001944 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001945 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001946 struct hci_cp_set_conn_encrypt cp;
1947 cp.handle = ev->handle;
1948 cp.encrypt = 0x01;
1949 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1950 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001951 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001952 conn->state = BT_CONNECTED;
1953 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001954 hci_conn_put(conn);
1955 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001956 } else {
1957 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001958
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001959 hci_conn_hold(conn);
1960 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1961 hci_conn_put(conn);
1962 }
1963
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001964 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001965 if (!ev->status) {
1966 struct hci_cp_set_conn_encrypt cp;
1967 cp.handle = ev->handle;
1968 cp.encrypt = 0x01;
1969 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1970 &cp);
1971 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001972 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001973 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001974 }
1975 }
1976
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001977unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001978 hci_dev_unlock(hdev);
1979}
1980
1981static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1982{
Johan Hedberg127178d2010-11-18 22:22:29 +02001983 struct hci_ev_remote_name *ev = (void *) skb->data;
1984 struct hci_conn *conn;
1985
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001986 BT_DBG("%s", hdev->name);
1987
1988 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001989
1990 hci_dev_lock(hdev);
1991
1992 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001993
1994 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1995 goto check_auth;
1996
1997 if (ev->status == 0)
1998 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001999 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002000 else
2001 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2002
2003check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002004 if (!conn)
2005 goto unlock;
2006
2007 if (!hci_outgoing_auth_needed(hdev, conn))
2008 goto unlock;
2009
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002010 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002011 struct hci_cp_auth_requested cp;
2012 cp.handle = __cpu_to_le16(conn->handle);
2013 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2014 }
2015
Johan Hedberg79c6c702011-04-28 11:28:55 -07002016unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002017 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002018}
2019
2020static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2021{
2022 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2023 struct hci_conn *conn;
2024
2025 BT_DBG("%s status %d", hdev->name, ev->status);
2026
2027 hci_dev_lock(hdev);
2028
2029 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2030 if (conn) {
2031 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002032 if (ev->encrypt) {
2033 /* Encryption implies authentication */
2034 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002035 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002036 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002037 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002038 conn->link_mode &= ~HCI_LM_ENCRYPT;
2039 }
2040
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002041 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002042
Marcel Holtmannf8558552008-07-14 20:13:49 +02002043 if (conn->state == BT_CONFIG) {
2044 if (!ev->status)
2045 conn->state = BT_CONNECTED;
2046
2047 hci_proto_connect_cfm(conn, ev->status);
2048 hci_conn_put(conn);
2049 } else
2050 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002051 }
2052
2053 hci_dev_unlock(hdev);
2054}
2055
2056static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2057{
2058 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2059 struct hci_conn *conn;
2060
2061 BT_DBG("%s status %d", hdev->name, ev->status);
2062
2063 hci_dev_lock(hdev);
2064
2065 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2066 if (conn) {
2067 if (!ev->status)
2068 conn->link_mode |= HCI_LM_SECURE;
2069
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002070 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002071
2072 hci_key_change_cfm(conn, ev->status);
2073 }
2074
2075 hci_dev_unlock(hdev);
2076}
2077
2078static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2079{
2080 struct hci_ev_remote_features *ev = (void *) skb->data;
2081 struct hci_conn *conn;
2082
2083 BT_DBG("%s status %d", hdev->name, ev->status);
2084
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002085 hci_dev_lock(hdev);
2086
2087 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002088 if (!conn)
2089 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002090
Johan Hedbergccd556f2010-11-10 17:11:51 +02002091 if (!ev->status)
2092 memcpy(conn->features, ev->features, 8);
2093
2094 if (conn->state != BT_CONFIG)
2095 goto unlock;
2096
2097 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2098 struct hci_cp_read_remote_ext_features cp;
2099 cp.handle = ev->handle;
2100 cp.page = 0x01;
2101 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002102 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002103 goto unlock;
2104 }
2105
Johan Hedberg127178d2010-11-18 22:22:29 +02002106 if (!ev->status) {
2107 struct hci_cp_remote_name_req cp;
2108 memset(&cp, 0, sizeof(cp));
2109 bacpy(&cp.bdaddr, &conn->dst);
2110 cp.pscan_rep_mode = 0x02;
2111 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002112 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2113 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002114 conn->dst_type, 0, NULL, 0,
2115 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002116
Johan Hedberg127178d2010-11-18 22:22:29 +02002117 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002118 conn->state = BT_CONNECTED;
2119 hci_proto_connect_cfm(conn, ev->status);
2120 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002121 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002122
Johan Hedbergccd556f2010-11-10 17:11:51 +02002123unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002124 hci_dev_unlock(hdev);
2125}
2126
2127static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2128{
2129 BT_DBG("%s", hdev->name);
2130}
2131
2132static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2133{
2134 BT_DBG("%s", hdev->name);
2135}
2136
2137static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2138{
2139 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2140 __u16 opcode;
2141
2142 skb_pull(skb, sizeof(*ev));
2143
2144 opcode = __le16_to_cpu(ev->opcode);
2145
2146 switch (opcode) {
2147 case HCI_OP_INQUIRY_CANCEL:
2148 hci_cc_inquiry_cancel(hdev, skb);
2149 break;
2150
2151 case HCI_OP_EXIT_PERIODIC_INQ:
2152 hci_cc_exit_periodic_inq(hdev, skb);
2153 break;
2154
2155 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2156 hci_cc_remote_name_req_cancel(hdev, skb);
2157 break;
2158
2159 case HCI_OP_ROLE_DISCOVERY:
2160 hci_cc_role_discovery(hdev, skb);
2161 break;
2162
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002163 case HCI_OP_READ_LINK_POLICY:
2164 hci_cc_read_link_policy(hdev, skb);
2165 break;
2166
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002167 case HCI_OP_WRITE_LINK_POLICY:
2168 hci_cc_write_link_policy(hdev, skb);
2169 break;
2170
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002171 case HCI_OP_READ_DEF_LINK_POLICY:
2172 hci_cc_read_def_link_policy(hdev, skb);
2173 break;
2174
2175 case HCI_OP_WRITE_DEF_LINK_POLICY:
2176 hci_cc_write_def_link_policy(hdev, skb);
2177 break;
2178
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002179 case HCI_OP_RESET:
2180 hci_cc_reset(hdev, skb);
2181 break;
2182
2183 case HCI_OP_WRITE_LOCAL_NAME:
2184 hci_cc_write_local_name(hdev, skb);
2185 break;
2186
2187 case HCI_OP_READ_LOCAL_NAME:
2188 hci_cc_read_local_name(hdev, skb);
2189 break;
2190
2191 case HCI_OP_WRITE_AUTH_ENABLE:
2192 hci_cc_write_auth_enable(hdev, skb);
2193 break;
2194
2195 case HCI_OP_WRITE_ENCRYPT_MODE:
2196 hci_cc_write_encrypt_mode(hdev, skb);
2197 break;
2198
2199 case HCI_OP_WRITE_SCAN_ENABLE:
2200 hci_cc_write_scan_enable(hdev, skb);
2201 break;
2202
2203 case HCI_OP_READ_CLASS_OF_DEV:
2204 hci_cc_read_class_of_dev(hdev, skb);
2205 break;
2206
2207 case HCI_OP_WRITE_CLASS_OF_DEV:
2208 hci_cc_write_class_of_dev(hdev, skb);
2209 break;
2210
2211 case HCI_OP_READ_VOICE_SETTING:
2212 hci_cc_read_voice_setting(hdev, skb);
2213 break;
2214
2215 case HCI_OP_WRITE_VOICE_SETTING:
2216 hci_cc_write_voice_setting(hdev, skb);
2217 break;
2218
2219 case HCI_OP_HOST_BUFFER_SIZE:
2220 hci_cc_host_buffer_size(hdev, skb);
2221 break;
2222
Marcel Holtmann333140b2008-07-14 20:13:48 +02002223 case HCI_OP_WRITE_SSP_MODE:
2224 hci_cc_write_ssp_mode(hdev, skb);
2225 break;
2226
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002227 case HCI_OP_READ_LOCAL_VERSION:
2228 hci_cc_read_local_version(hdev, skb);
2229 break;
2230
2231 case HCI_OP_READ_LOCAL_COMMANDS:
2232 hci_cc_read_local_commands(hdev, skb);
2233 break;
2234
2235 case HCI_OP_READ_LOCAL_FEATURES:
2236 hci_cc_read_local_features(hdev, skb);
2237 break;
2238
Andre Guedes971e3a42011-06-30 19:20:52 -03002239 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2240 hci_cc_read_local_ext_features(hdev, skb);
2241 break;
2242
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002243 case HCI_OP_READ_BUFFER_SIZE:
2244 hci_cc_read_buffer_size(hdev, skb);
2245 break;
2246
2247 case HCI_OP_READ_BD_ADDR:
2248 hci_cc_read_bd_addr(hdev, skb);
2249 break;
2250
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002251 case HCI_OP_READ_DATA_BLOCK_SIZE:
2252 hci_cc_read_data_block_size(hdev, skb);
2253 break;
2254
Johan Hedberg23bb5762010-12-21 23:01:27 +02002255 case HCI_OP_WRITE_CA_TIMEOUT:
2256 hci_cc_write_ca_timeout(hdev, skb);
2257 break;
2258
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002259 case HCI_OP_READ_FLOW_CONTROL_MODE:
2260 hci_cc_read_flow_control_mode(hdev, skb);
2261 break;
2262
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002263 case HCI_OP_READ_LOCAL_AMP_INFO:
2264 hci_cc_read_local_amp_info(hdev, skb);
2265 break;
2266
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002267 case HCI_OP_DELETE_STORED_LINK_KEY:
2268 hci_cc_delete_stored_link_key(hdev, skb);
2269 break;
2270
Johan Hedbergd5859e22011-01-25 01:19:58 +02002271 case HCI_OP_SET_EVENT_MASK:
2272 hci_cc_set_event_mask(hdev, skb);
2273 break;
2274
2275 case HCI_OP_WRITE_INQUIRY_MODE:
2276 hci_cc_write_inquiry_mode(hdev, skb);
2277 break;
2278
2279 case HCI_OP_READ_INQ_RSP_TX_POWER:
2280 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2281 break;
2282
2283 case HCI_OP_SET_EVENT_FLT:
2284 hci_cc_set_event_flt(hdev, skb);
2285 break;
2286
Johan Hedberg980e1a52011-01-22 06:10:07 +02002287 case HCI_OP_PIN_CODE_REPLY:
2288 hci_cc_pin_code_reply(hdev, skb);
2289 break;
2290
2291 case HCI_OP_PIN_CODE_NEG_REPLY:
2292 hci_cc_pin_code_neg_reply(hdev, skb);
2293 break;
2294
Szymon Jancc35938b2011-03-22 13:12:21 +01002295 case HCI_OP_READ_LOCAL_OOB_DATA:
2296 hci_cc_read_local_oob_data_reply(hdev, skb);
2297 break;
2298
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002299 case HCI_OP_LE_READ_BUFFER_SIZE:
2300 hci_cc_le_read_buffer_size(hdev, skb);
2301 break;
2302
Johan Hedberga5c29682011-02-19 12:05:57 -03002303 case HCI_OP_USER_CONFIRM_REPLY:
2304 hci_cc_user_confirm_reply(hdev, skb);
2305 break;
2306
2307 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2308 hci_cc_user_confirm_neg_reply(hdev, skb);
2309 break;
2310
Brian Gix1143d452011-11-23 08:28:34 -08002311 case HCI_OP_USER_PASSKEY_REPLY:
2312 hci_cc_user_passkey_reply(hdev, skb);
2313 break;
2314
2315 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2316 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002317
2318 case HCI_OP_LE_SET_SCAN_PARAM:
2319 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002320 break;
2321
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002322 case HCI_OP_LE_SET_SCAN_ENABLE:
2323 hci_cc_le_set_scan_enable(hdev, skb);
2324 break;
2325
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002326 case HCI_OP_LE_LTK_REPLY:
2327 hci_cc_le_ltk_reply(hdev, skb);
2328 break;
2329
2330 case HCI_OP_LE_LTK_NEG_REPLY:
2331 hci_cc_le_ltk_neg_reply(hdev, skb);
2332 break;
2333
Andre Guedesf9b49302011-06-30 19:20:53 -03002334 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2335 hci_cc_write_le_host_supported(hdev, skb);
2336 break;
2337
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002338 default:
2339 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2340 break;
2341 }
2342
Ville Tervo6bd32322011-02-16 16:32:41 +02002343 if (ev->opcode != HCI_OP_NOP)
2344 del_timer(&hdev->cmd_timer);
2345
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002346 if (ev->ncmd) {
2347 atomic_set(&hdev->cmd_cnt, 1);
2348 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002349 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002350 }
2351}
2352
2353static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2354{
2355 struct hci_ev_cmd_status *ev = (void *) skb->data;
2356 __u16 opcode;
2357
2358 skb_pull(skb, sizeof(*ev));
2359
2360 opcode = __le16_to_cpu(ev->opcode);
2361
2362 switch (opcode) {
2363 case HCI_OP_INQUIRY:
2364 hci_cs_inquiry(hdev, ev->status);
2365 break;
2366
2367 case HCI_OP_CREATE_CONN:
2368 hci_cs_create_conn(hdev, ev->status);
2369 break;
2370
2371 case HCI_OP_ADD_SCO:
2372 hci_cs_add_sco(hdev, ev->status);
2373 break;
2374
Marcel Holtmannf8558552008-07-14 20:13:49 +02002375 case HCI_OP_AUTH_REQUESTED:
2376 hci_cs_auth_requested(hdev, ev->status);
2377 break;
2378
2379 case HCI_OP_SET_CONN_ENCRYPT:
2380 hci_cs_set_conn_encrypt(hdev, ev->status);
2381 break;
2382
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002383 case HCI_OP_REMOTE_NAME_REQ:
2384 hci_cs_remote_name_req(hdev, ev->status);
2385 break;
2386
Marcel Holtmann769be972008-07-14 20:13:49 +02002387 case HCI_OP_READ_REMOTE_FEATURES:
2388 hci_cs_read_remote_features(hdev, ev->status);
2389 break;
2390
2391 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2392 hci_cs_read_remote_ext_features(hdev, ev->status);
2393 break;
2394
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002395 case HCI_OP_SETUP_SYNC_CONN:
2396 hci_cs_setup_sync_conn(hdev, ev->status);
2397 break;
2398
2399 case HCI_OP_SNIFF_MODE:
2400 hci_cs_sniff_mode(hdev, ev->status);
2401 break;
2402
2403 case HCI_OP_EXIT_SNIFF_MODE:
2404 hci_cs_exit_sniff_mode(hdev, ev->status);
2405 break;
2406
Johan Hedberg8962ee72011-01-20 12:40:27 +02002407 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002408 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002409 break;
2410
Ville Tervofcd89c02011-02-10 22:38:47 -03002411 case HCI_OP_LE_CREATE_CONN:
2412 hci_cs_le_create_conn(hdev, ev->status);
2413 break;
2414
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002415 case HCI_OP_LE_START_ENC:
2416 hci_cs_le_start_enc(hdev, ev->status);
2417 break;
2418
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002419 default:
2420 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2421 break;
2422 }
2423
Ville Tervo6bd32322011-02-16 16:32:41 +02002424 if (ev->opcode != HCI_OP_NOP)
2425 del_timer(&hdev->cmd_timer);
2426
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002427 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002428 atomic_set(&hdev->cmd_cnt, 1);
2429 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002430 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002431 }
2432}
2433
2434static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2435{
2436 struct hci_ev_role_change *ev = (void *) skb->data;
2437 struct hci_conn *conn;
2438
2439 BT_DBG("%s status %d", hdev->name, ev->status);
2440
2441 hci_dev_lock(hdev);
2442
2443 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2444 if (conn) {
2445 if (!ev->status) {
2446 if (ev->role)
2447 conn->link_mode &= ~HCI_LM_MASTER;
2448 else
2449 conn->link_mode |= HCI_LM_MASTER;
2450 }
2451
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002452 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002453
2454 hci_role_switch_cfm(conn, ev->status, ev->role);
2455 }
2456
2457 hci_dev_unlock(hdev);
2458}
2459
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2461{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002462 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002463 int i;
2464
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002465 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2466 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2467 return;
2468 }
2469
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002470 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2471 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002472 BT_DBG("%s bad parameters", hdev->name);
2473 return;
2474 }
2475
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002476 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2477
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002478 for (i = 0; i < ev->num_hndl; i++) {
2479 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002480 struct hci_conn *conn;
2481 __u16 handle, count;
2482
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002483 handle = __le16_to_cpu(info->handle);
2484 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485
2486 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002487 if (!conn)
2488 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002489
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002490 conn->sent -= count;
2491
2492 switch (conn->type) {
2493 case ACL_LINK:
2494 hdev->acl_cnt += count;
2495 if (hdev->acl_cnt > hdev->acl_pkts)
2496 hdev->acl_cnt = hdev->acl_pkts;
2497 break;
2498
2499 case LE_LINK:
2500 if (hdev->le_pkts) {
2501 hdev->le_cnt += count;
2502 if (hdev->le_cnt > hdev->le_pkts)
2503 hdev->le_cnt = hdev->le_pkts;
2504 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002505 hdev->acl_cnt += count;
2506 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507 hdev->acl_cnt = hdev->acl_pkts;
2508 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002509 break;
2510
2511 case SCO_LINK:
2512 hdev->sco_cnt += count;
2513 if (hdev->sco_cnt > hdev->sco_pkts)
2514 hdev->sco_cnt = hdev->sco_pkts;
2515 break;
2516
2517 default:
2518 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2519 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002520 }
2521 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002522
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002523 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524}
2525
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002526static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002527 struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002528{
2529 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2530 int i;
2531
2532 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2533 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2534 return;
2535 }
2536
2537 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2538 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2539 BT_DBG("%s bad parameters", hdev->name);
2540 return;
2541 }
2542
2543 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2544 ev->num_hndl);
2545
2546 for (i = 0; i < ev->num_hndl; i++) {
2547 struct hci_comp_blocks_info *info = &ev->handles[i];
2548 struct hci_conn *conn;
2549 __u16 handle, block_count;
2550
2551 handle = __le16_to_cpu(info->handle);
2552 block_count = __le16_to_cpu(info->blocks);
2553
2554 conn = hci_conn_hash_lookup_handle(hdev, handle);
2555 if (!conn)
2556 continue;
2557
2558 conn->sent -= block_count;
2559
2560 switch (conn->type) {
2561 case ACL_LINK:
2562 hdev->block_cnt += block_count;
2563 if (hdev->block_cnt > hdev->num_blocks)
2564 hdev->block_cnt = hdev->num_blocks;
2565 break;
2566
2567 default:
2568 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2569 break;
2570 }
2571 }
2572
2573 queue_work(hdev->workqueue, &hdev->tx_work);
2574}
2575
Marcel Holtmann04837f62006-07-03 10:02:33 +02002576static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002578 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002579 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580
2581 BT_DBG("%s status %d", hdev->name, ev->status);
2582
2583 hci_dev_lock(hdev);
2584
Marcel Holtmann04837f62006-07-03 10:02:33 +02002585 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2586 if (conn) {
2587 conn->mode = ev->mode;
2588 conn->interval = __le16_to_cpu(ev->interval);
2589
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002590 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002591 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002592 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002593 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002594 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002595 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002596
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002597 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002598 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002599 }
2600
2601 hci_dev_unlock(hdev);
2602}
2603
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2605{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002606 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2607 struct hci_conn *conn;
2608
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002609 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002610
2611 hci_dev_lock(hdev);
2612
2613 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002614 if (!conn)
2615 goto unlock;
2616
2617 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002618 hci_conn_hold(conn);
2619 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2620 hci_conn_put(conn);
2621 }
2622
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002623 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002624 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2625 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002626 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002627 u8 secure;
2628
2629 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2630 secure = 1;
2631 else
2632 secure = 0;
2633
Johan Hedberg744cf192011-11-08 20:40:14 +02002634 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002635 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002636
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002637unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002638 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002639}
2640
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2642{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002643 struct hci_ev_link_key_req *ev = (void *) skb->data;
2644 struct hci_cp_link_key_reply cp;
2645 struct hci_conn *conn;
2646 struct link_key *key;
2647
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002648 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002649
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002650 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002651 return;
2652
2653 hci_dev_lock(hdev);
2654
2655 key = hci_find_link_key(hdev, &ev->bdaddr);
2656 if (!key) {
2657 BT_DBG("%s link key not found for %s", hdev->name,
2658 batostr(&ev->bdaddr));
2659 goto not_found;
2660 }
2661
2662 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2663 batostr(&ev->bdaddr));
2664
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002665 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002666 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002667 BT_DBG("%s ignoring debug key", hdev->name);
2668 goto not_found;
2669 }
2670
2671 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002672 if (conn) {
2673 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2674 conn->auth_type != 0xff &&
2675 (conn->auth_type & 0x01)) {
2676 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2677 goto not_found;
2678 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002679
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002680 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2681 conn->pending_sec_level == BT_SECURITY_HIGH) {
2682 BT_DBG("%s ignoring key unauthenticated for high \
2683 security", hdev->name);
2684 goto not_found;
2685 }
2686
2687 conn->key_type = key->type;
2688 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002689 }
2690
2691 bacpy(&cp.bdaddr, &ev->bdaddr);
2692 memcpy(cp.link_key, key->val, 16);
2693
2694 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2695
2696 hci_dev_unlock(hdev);
2697
2698 return;
2699
2700not_found:
2701 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2702 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002703}
2704
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2706{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002707 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2708 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002709 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002710
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002711 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002712
2713 hci_dev_lock(hdev);
2714
2715 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2716 if (conn) {
2717 hci_conn_hold(conn);
2718 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002719 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002720
2721 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2722 conn->key_type = ev->key_type;
2723
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002724 hci_conn_put(conn);
2725 }
2726
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002727 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002728 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002729 ev->key_type, pin_len);
2730
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002731 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002732}
2733
Marcel Holtmann04837f62006-07-03 10:02:33 +02002734static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2735{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002736 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002737 struct hci_conn *conn;
2738
2739 BT_DBG("%s status %d", hdev->name, ev->status);
2740
2741 hci_dev_lock(hdev);
2742
2743 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744 if (conn && !ev->status) {
2745 struct inquiry_entry *ie;
2746
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002747 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2748 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749 ie->data.clock_offset = ev->clock_offset;
2750 ie->timestamp = jiffies;
2751 }
2752 }
2753
2754 hci_dev_unlock(hdev);
2755}
2756
Marcel Holtmanna8746412008-07-14 20:13:46 +02002757static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2758{
2759 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2760 struct hci_conn *conn;
2761
2762 BT_DBG("%s status %d", hdev->name, ev->status);
2763
2764 hci_dev_lock(hdev);
2765
2766 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2767 if (conn && !ev->status)
2768 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2769
2770 hci_dev_unlock(hdev);
2771}
2772
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002773static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2774{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002775 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002776 struct inquiry_entry *ie;
2777
2778 BT_DBG("%s", hdev->name);
2779
2780 hci_dev_lock(hdev);
2781
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002782 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2783 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002784 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2785 ie->timestamp = jiffies;
2786 }
2787
2788 hci_dev_unlock(hdev);
2789}
2790
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002791static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2792{
2793 struct inquiry_data data;
2794 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002795 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002796
2797 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2798
2799 if (!num_rsp)
2800 return;
2801
2802 hci_dev_lock(hdev);
2803
2804 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002805 struct inquiry_info_with_rssi_and_pscan_mode *info;
2806 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002807
Johan Hedberge17acd42011-03-30 23:57:16 +03002808 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002809 bacpy(&data.bdaddr, &info->bdaddr);
2810 data.pscan_rep_mode = info->pscan_rep_mode;
2811 data.pscan_period_mode = info->pscan_period_mode;
2812 data.pscan_mode = info->pscan_mode;
2813 memcpy(data.dev_class, info->dev_class, 3);
2814 data.clock_offset = info->clock_offset;
2815 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002816 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002817
2818 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002819 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002820 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002821 info->dev_class, info->rssi,
2822 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002823 }
2824 } else {
2825 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2826
Johan Hedberge17acd42011-03-30 23:57:16 +03002827 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002828 bacpy(&data.bdaddr, &info->bdaddr);
2829 data.pscan_rep_mode = info->pscan_rep_mode;
2830 data.pscan_period_mode = info->pscan_period_mode;
2831 data.pscan_mode = 0x00;
2832 memcpy(data.dev_class, info->dev_class, 3);
2833 data.clock_offset = info->clock_offset;
2834 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002835 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002836 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002837 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002838 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002839 info->dev_class, info->rssi,
2840 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002841 }
2842 }
2843
2844 hci_dev_unlock(hdev);
2845}
2846
2847static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2848{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002849 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2850 struct hci_conn *conn;
2851
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002852 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002853
Marcel Holtmann41a96212008-07-14 20:13:48 +02002854 hci_dev_lock(hdev);
2855
2856 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002857 if (!conn)
2858 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002859
Johan Hedbergccd556f2010-11-10 17:11:51 +02002860 if (!ev->status && ev->page == 0x01) {
2861 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002862
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002863 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2864 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002865 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002866
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002867 if (ev->features[0] & LMP_HOST_SSP)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002868 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002869 }
2870
Johan Hedbergccd556f2010-11-10 17:11:51 +02002871 if (conn->state != BT_CONFIG)
2872 goto unlock;
2873
Johan Hedberg127178d2010-11-18 22:22:29 +02002874 if (!ev->status) {
2875 struct hci_cp_remote_name_req cp;
2876 memset(&cp, 0, sizeof(cp));
2877 bacpy(&cp.bdaddr, &conn->dst);
2878 cp.pscan_rep_mode = 0x02;
2879 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002880 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2881 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002882 conn->dst_type, 0, NULL, 0,
2883 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002884
Johan Hedberg127178d2010-11-18 22:22:29 +02002885 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002886 conn->state = BT_CONNECTED;
2887 hci_proto_connect_cfm(conn, ev->status);
2888 hci_conn_put(conn);
2889 }
2890
2891unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002892 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002893}
2894
2895static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2896{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002897 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2898 struct hci_conn *conn;
2899
2900 BT_DBG("%s status %d", hdev->name, ev->status);
2901
2902 hci_dev_lock(hdev);
2903
2904 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002905 if (!conn) {
2906 if (ev->link_type == ESCO_LINK)
2907 goto unlock;
2908
2909 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2910 if (!conn)
2911 goto unlock;
2912
2913 conn->type = SCO_LINK;
2914 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002915
Marcel Holtmann732547f2009-04-19 19:14:14 +02002916 switch (ev->status) {
2917 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002918 conn->handle = __le16_to_cpu(ev->handle);
2919 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002920
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002921 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002922 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002923 break;
2924
Stephen Coe705e5712010-02-16 11:29:44 -05002925 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002926 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002927 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002928 case 0x1f: /* Unspecified error */
2929 if (conn->out && conn->attempt < 2) {
2930 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2931 (hdev->esco_type & EDR_ESCO_MASK);
2932 hci_setup_sync(conn, conn->link->handle);
2933 goto unlock;
2934 }
2935 /* fall through */
2936
2937 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002938 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002939 break;
2940 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002941
2942 hci_proto_connect_cfm(conn, ev->status);
2943 if (ev->status)
2944 hci_conn_del(conn);
2945
2946unlock:
2947 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002948}
2949
2950static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2951{
2952 BT_DBG("%s", hdev->name);
2953}
2954
Marcel Holtmann04837f62006-07-03 10:02:33 +02002955static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2956{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002957 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002958
2959 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002960}
2961
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002962static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2963{
2964 struct inquiry_data data;
2965 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2966 int num_rsp = *((__u8 *) skb->data);
2967
2968 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2969
2970 if (!num_rsp)
2971 return;
2972
2973 hci_dev_lock(hdev);
2974
Johan Hedberge17acd42011-03-30 23:57:16 +03002975 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002976 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002977
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002978 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002979 data.pscan_rep_mode = info->pscan_rep_mode;
2980 data.pscan_period_mode = info->pscan_period_mode;
2981 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002982 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002983 data.clock_offset = info->clock_offset;
2984 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002985 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002986
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002987 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002988 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002989 sizeof(info->data),
2990 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002991 else
2992 name_known = true;
2993
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002994 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002995 &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002996 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002997 info->dev_class, info->rssi, !name_known,
2998 ssp, info->data, sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002999 }
3000
3001 hci_dev_unlock(hdev);
3002}
3003
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003004static inline u8 hci_get_auth_req(struct hci_conn *conn)
3005{
3006 /* If remote requests dedicated bonding follow that lead */
3007 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3008 /* If both remote and local IO capabilities allow MITM
3009 * protection then require it, otherwise don't */
3010 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3011 return 0x02;
3012 else
3013 return 0x03;
3014 }
3015
3016 /* If remote requests no-bonding follow that lead */
3017 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003018 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003019
3020 return conn->auth_type;
3021}
3022
Marcel Holtmann04936842008-07-14 20:13:48 +02003023static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3024{
3025 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3026 struct hci_conn *conn;
3027
3028 BT_DBG("%s", hdev->name);
3029
3030 hci_dev_lock(hdev);
3031
3032 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003033 if (!conn)
3034 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003035
Johan Hedberg03b555e2011-01-04 15:40:05 +02003036 hci_conn_hold(conn);
3037
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003038 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003039 goto unlock;
3040
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003041 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003042 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003043 struct hci_cp_io_capability_reply cp;
3044
3045 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303046 /* Change the IO capability from KeyboardDisplay
3047 * to DisplayYesNo as it is not supported by BT spec. */
3048 cp.capability = (conn->io_capability == 0x04) ?
3049 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003050 conn->auth_type = hci_get_auth_req(conn);
3051 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003052
Johan Hedberg58a681e2012-01-16 06:47:28 +02003053 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003054 hci_find_remote_oob_data(hdev, &conn->dst))
3055 cp.oob_data = 0x01;
3056 else
3057 cp.oob_data = 0x00;
3058
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003059 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3060 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003061 } else {
3062 struct hci_cp_io_capability_neg_reply cp;
3063
3064 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003065 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003066
3067 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3068 sizeof(cp), &cp);
3069 }
3070
3071unlock:
3072 hci_dev_unlock(hdev);
3073}
3074
3075static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3076{
3077 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3078 struct hci_conn *conn;
3079
3080 BT_DBG("%s", hdev->name);
3081
3082 hci_dev_lock(hdev);
3083
3084 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3085 if (!conn)
3086 goto unlock;
3087
Johan Hedberg03b555e2011-01-04 15:40:05 +02003088 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003089 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003090 if (ev->oob_data)
3091 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003092
3093unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003094 hci_dev_unlock(hdev);
3095}
3096
Johan Hedberga5c29682011-02-19 12:05:57 -03003097static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3098 struct sk_buff *skb)
3099{
3100 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003101 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003102 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003103
3104 BT_DBG("%s", hdev->name);
3105
3106 hci_dev_lock(hdev);
3107
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003108 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003109 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003110
Johan Hedberg7a828902011-04-28 11:28:53 -07003111 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3112 if (!conn)
3113 goto unlock;
3114
3115 loc_mitm = (conn->auth_type & 0x01);
3116 rem_mitm = (conn->remote_auth & 0x01);
3117
3118 /* If we require MITM but the remote device can't provide that
3119 * (it has NoInputNoOutput) then reject the confirmation
3120 * request. The only exception is when we're dedicated bonding
3121 * initiators (connect_cfm_cb set) since then we always have the MITM
3122 * bit set. */
3123 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3124 BT_DBG("Rejecting request: remote device can't provide MITM");
3125 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3126 sizeof(ev->bdaddr), &ev->bdaddr);
3127 goto unlock;
3128 }
3129
3130 /* If no side requires MITM protection; auto-accept */
3131 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3132 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003133
3134 /* If we're not the initiators request authorization to
3135 * proceed from user space (mgmt_user_confirm with
3136 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003137 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003138 BT_DBG("Confirming auto-accept as acceptor");
3139 confirm_hint = 1;
3140 goto confirm;
3141 }
3142
Johan Hedberg9f616562011-04-28 11:28:54 -07003143 BT_DBG("Auto-accept of user confirmation with %ums delay",
3144 hdev->auto_accept_delay);
3145
3146 if (hdev->auto_accept_delay > 0) {
3147 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3148 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3149 goto unlock;
3150 }
3151
Johan Hedberg7a828902011-04-28 11:28:53 -07003152 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3153 sizeof(ev->bdaddr), &ev->bdaddr);
3154 goto unlock;
3155 }
3156
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003157confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003158 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003159 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003160
3161unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003162 hci_dev_unlock(hdev);
3163}
3164
Brian Gix1143d452011-11-23 08:28:34 -08003165static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3166 struct sk_buff *skb)
3167{
3168 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3169
3170 BT_DBG("%s", hdev->name);
3171
3172 hci_dev_lock(hdev);
3173
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003174 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003175 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003176
3177 hci_dev_unlock(hdev);
3178}
3179
Marcel Holtmann04936842008-07-14 20:13:48 +02003180static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3181{
3182 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3183 struct hci_conn *conn;
3184
3185 BT_DBG("%s", hdev->name);
3186
3187 hci_dev_lock(hdev);
3188
3189 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003190 if (!conn)
3191 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003192
Johan Hedberg2a611692011-02-19 12:06:00 -03003193 /* To avoid duplicate auth_failed events to user space we check
3194 * the HCI_CONN_AUTH_PEND flag which will be set if we
3195 * initiated the authentication. A traditional auth_complete
3196 * event gets always produced as initiator and is also mapped to
3197 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003198 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003199 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003200 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003201
3202 hci_conn_put(conn);
3203
3204unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003205 hci_dev_unlock(hdev);
3206}
3207
Marcel Holtmann41a96212008-07-14 20:13:48 +02003208static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3209{
3210 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3211 struct inquiry_entry *ie;
3212
3213 BT_DBG("%s", hdev->name);
3214
3215 hci_dev_lock(hdev);
3216
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003217 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3218 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003219 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003220
3221 hci_dev_unlock(hdev);
3222}
3223
Szymon Janc2763eda2011-03-22 13:12:22 +01003224static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003225 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003226{
3227 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3228 struct oob_data *data;
3229
3230 BT_DBG("%s", hdev->name);
3231
3232 hci_dev_lock(hdev);
3233
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003234 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003235 goto unlock;
3236
Szymon Janc2763eda2011-03-22 13:12:22 +01003237 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3238 if (data) {
3239 struct hci_cp_remote_oob_data_reply cp;
3240
3241 bacpy(&cp.bdaddr, &ev->bdaddr);
3242 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3243 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3244
3245 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3246 &cp);
3247 } else {
3248 struct hci_cp_remote_oob_data_neg_reply cp;
3249
3250 bacpy(&cp.bdaddr, &ev->bdaddr);
3251 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3252 &cp);
3253 }
3254
Szymon Jance1ba1f12011-04-06 13:01:59 +02003255unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003256 hci_dev_unlock(hdev);
3257}
3258
Ville Tervofcd89c02011-02-10 22:38:47 -03003259static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3260{
3261 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3262 struct hci_conn *conn;
3263
3264 BT_DBG("%s status %d", hdev->name, ev->status);
3265
3266 hci_dev_lock(hdev);
3267
3268 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003269 if (!conn) {
3270 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3271 if (!conn) {
3272 BT_ERR("No memory for new connection");
3273 hci_dev_unlock(hdev);
3274 return;
3275 }
Andre Guedes29b79882011-05-31 14:20:54 -03003276
3277 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003278 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003279
3280 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003281 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3282 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003283 hci_proto_connect_cfm(conn, ev->status);
3284 conn->state = BT_CLOSED;
3285 hci_conn_del(conn);
3286 goto unlock;
3287 }
3288
Johan Hedbergb644ba32012-01-17 21:48:47 +02003289 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3290 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003291 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003292
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003293 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003294 conn->handle = __le16_to_cpu(ev->handle);
3295 conn->state = BT_CONNECTED;
3296
3297 hci_conn_hold_device(conn);
3298 hci_conn_add_sysfs(conn);
3299
3300 hci_proto_connect_cfm(conn, ev->status);
3301
3302unlock:
3303 hci_dev_unlock(hdev);
3304}
3305
Andre Guedes9aa04c92011-05-26 16:23:51 -03003306static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3307 struct sk_buff *skb)
3308{
Andre Guedese95beb42011-09-26 20:48:35 -03003309 u8 num_reports = skb->data[0];
3310 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003311 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003312
3313 hci_dev_lock(hdev);
3314
Andre Guedese95beb42011-09-26 20:48:35 -03003315 while (num_reports--) {
3316 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003317
Andre Guedes9aa04c92011-05-26 16:23:51 -03003318 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003319
Andre Guedes3c9e9192012-01-10 18:20:50 -03003320 rssi = ev->data[ev->length];
3321 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003322 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003323
Andre Guedese95beb42011-09-26 20:48:35 -03003324 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003325 }
3326
3327 hci_dev_unlock(hdev);
3328}
3329
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003330static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3331 struct sk_buff *skb)
3332{
3333 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3334 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003335 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003336 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003337 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003338
3339 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3340
3341 hci_dev_lock(hdev);
3342
3343 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003344 if (conn == NULL)
3345 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003346
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003347 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3348 if (ltk == NULL)
3349 goto not_found;
3350
3351 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003352 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003353
3354 if (ltk->authenticated)
3355 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003356
3357 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3358
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003359 if (ltk->type & HCI_SMP_STK) {
3360 list_del(&ltk->list);
3361 kfree(ltk);
3362 }
3363
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003364 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003365
3366 return;
3367
3368not_found:
3369 neg.handle = ev->handle;
3370 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3371 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003372}
3373
Ville Tervofcd89c02011-02-10 22:38:47 -03003374static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3375{
3376 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3377
3378 skb_pull(skb, sizeof(*le_ev));
3379
3380 switch (le_ev->subevent) {
3381 case HCI_EV_LE_CONN_COMPLETE:
3382 hci_le_conn_complete_evt(hdev, skb);
3383 break;
3384
Andre Guedes9aa04c92011-05-26 16:23:51 -03003385 case HCI_EV_LE_ADVERTISING_REPORT:
3386 hci_le_adv_report_evt(hdev, skb);
3387 break;
3388
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003389 case HCI_EV_LE_LTK_REQ:
3390 hci_le_ltk_request_evt(hdev, skb);
3391 break;
3392
Ville Tervofcd89c02011-02-10 22:38:47 -03003393 default:
3394 break;
3395 }
3396}
3397
Linus Torvalds1da177e2005-04-16 15:20:36 -07003398void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3399{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003400 struct hci_event_hdr *hdr = (void *) skb->data;
3401 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003402
3403 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3404
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003405 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003406 case HCI_EV_INQUIRY_COMPLETE:
3407 hci_inquiry_complete_evt(hdev, skb);
3408 break;
3409
3410 case HCI_EV_INQUIRY_RESULT:
3411 hci_inquiry_result_evt(hdev, skb);
3412 break;
3413
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003414 case HCI_EV_CONN_COMPLETE:
3415 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003416 break;
3417
Linus Torvalds1da177e2005-04-16 15:20:36 -07003418 case HCI_EV_CONN_REQUEST:
3419 hci_conn_request_evt(hdev, skb);
3420 break;
3421
Linus Torvalds1da177e2005-04-16 15:20:36 -07003422 case HCI_EV_DISCONN_COMPLETE:
3423 hci_disconn_complete_evt(hdev, skb);
3424 break;
3425
Linus Torvalds1da177e2005-04-16 15:20:36 -07003426 case HCI_EV_AUTH_COMPLETE:
3427 hci_auth_complete_evt(hdev, skb);
3428 break;
3429
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003430 case HCI_EV_REMOTE_NAME:
3431 hci_remote_name_evt(hdev, skb);
3432 break;
3433
Linus Torvalds1da177e2005-04-16 15:20:36 -07003434 case HCI_EV_ENCRYPT_CHANGE:
3435 hci_encrypt_change_evt(hdev, skb);
3436 break;
3437
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003438 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3439 hci_change_link_key_complete_evt(hdev, skb);
3440 break;
3441
3442 case HCI_EV_REMOTE_FEATURES:
3443 hci_remote_features_evt(hdev, skb);
3444 break;
3445
3446 case HCI_EV_REMOTE_VERSION:
3447 hci_remote_version_evt(hdev, skb);
3448 break;
3449
3450 case HCI_EV_QOS_SETUP_COMPLETE:
3451 hci_qos_setup_complete_evt(hdev, skb);
3452 break;
3453
3454 case HCI_EV_CMD_COMPLETE:
3455 hci_cmd_complete_evt(hdev, skb);
3456 break;
3457
3458 case HCI_EV_CMD_STATUS:
3459 hci_cmd_status_evt(hdev, skb);
3460 break;
3461
3462 case HCI_EV_ROLE_CHANGE:
3463 hci_role_change_evt(hdev, skb);
3464 break;
3465
3466 case HCI_EV_NUM_COMP_PKTS:
3467 hci_num_comp_pkts_evt(hdev, skb);
3468 break;
3469
3470 case HCI_EV_MODE_CHANGE:
3471 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003472 break;
3473
3474 case HCI_EV_PIN_CODE_REQ:
3475 hci_pin_code_request_evt(hdev, skb);
3476 break;
3477
3478 case HCI_EV_LINK_KEY_REQ:
3479 hci_link_key_request_evt(hdev, skb);
3480 break;
3481
3482 case HCI_EV_LINK_KEY_NOTIFY:
3483 hci_link_key_notify_evt(hdev, skb);
3484 break;
3485
3486 case HCI_EV_CLOCK_OFFSET:
3487 hci_clock_offset_evt(hdev, skb);
3488 break;
3489
Marcel Holtmanna8746412008-07-14 20:13:46 +02003490 case HCI_EV_PKT_TYPE_CHANGE:
3491 hci_pkt_type_change_evt(hdev, skb);
3492 break;
3493
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003494 case HCI_EV_PSCAN_REP_MODE:
3495 hci_pscan_rep_mode_evt(hdev, skb);
3496 break;
3497
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003498 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3499 hci_inquiry_result_with_rssi_evt(hdev, skb);
3500 break;
3501
3502 case HCI_EV_REMOTE_EXT_FEATURES:
3503 hci_remote_ext_features_evt(hdev, skb);
3504 break;
3505
3506 case HCI_EV_SYNC_CONN_COMPLETE:
3507 hci_sync_conn_complete_evt(hdev, skb);
3508 break;
3509
3510 case HCI_EV_SYNC_CONN_CHANGED:
3511 hci_sync_conn_changed_evt(hdev, skb);
3512 break;
3513
Marcel Holtmann04837f62006-07-03 10:02:33 +02003514 case HCI_EV_SNIFF_SUBRATE:
3515 hci_sniff_subrate_evt(hdev, skb);
3516 break;
3517
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003518 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3519 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003520 break;
3521
Marcel Holtmann04936842008-07-14 20:13:48 +02003522 case HCI_EV_IO_CAPA_REQUEST:
3523 hci_io_capa_request_evt(hdev, skb);
3524 break;
3525
Johan Hedberg03b555e2011-01-04 15:40:05 +02003526 case HCI_EV_IO_CAPA_REPLY:
3527 hci_io_capa_reply_evt(hdev, skb);
3528 break;
3529
Johan Hedberga5c29682011-02-19 12:05:57 -03003530 case HCI_EV_USER_CONFIRM_REQUEST:
3531 hci_user_confirm_request_evt(hdev, skb);
3532 break;
3533
Brian Gix1143d452011-11-23 08:28:34 -08003534 case HCI_EV_USER_PASSKEY_REQUEST:
3535 hci_user_passkey_request_evt(hdev, skb);
3536 break;
3537
Marcel Holtmann04936842008-07-14 20:13:48 +02003538 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3539 hci_simple_pair_complete_evt(hdev, skb);
3540 break;
3541
Marcel Holtmann41a96212008-07-14 20:13:48 +02003542 case HCI_EV_REMOTE_HOST_FEATURES:
3543 hci_remote_host_features_evt(hdev, skb);
3544 break;
3545
Ville Tervofcd89c02011-02-10 22:38:47 -03003546 case HCI_EV_LE_META:
3547 hci_le_meta_evt(hdev, skb);
3548 break;
3549
Szymon Janc2763eda2011-03-22 13:12:22 +01003550 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3551 hci_remote_oob_data_request_evt(hdev, skb);
3552 break;
3553
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003554 case HCI_EV_NUM_COMP_BLOCKS:
3555 hci_num_comp_blocks_evt(hdev, skb);
3556 break;
3557
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003558 default:
3559 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003560 break;
3561 }
3562
3563 kfree_skb(skb);
3564 hdev->stat.evt_rx++;
3565}