blob: e920cd520a82b701e5be0485c6da45cdc0a52ed8 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <net/sock.h>
39
40#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020041#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <asm/unaligned.h>
43
44#include <net/bluetooth/bluetooth.h>
45#include <net/bluetooth/hci_core.h>
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047/* Handle HCI Event packets */
48
Marcel Holtmanna9de9242007-10-20 13:33:56 +020049static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070050{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020051 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
Marcel Holtmanna9de9242007-10-20 13:33:56 +020053 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Andre Guedese6d465c2011-11-09 17:14:26 -030055 if (status) {
56 hci_dev_lock(hdev);
57 mgmt_stop_discovery_failed(hdev, status);
58 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020059 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030060 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
Andre Guedes89352e72011-11-04 14:16:53 -030062 clear_bit(HCI_INQUIRY, &hdev->flags);
63
Johan Hedberg56e5cb82011-11-08 20:40:16 +020064 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020065 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020066 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010067
Johan Hedberg23bb5762010-12-21 23:01:27 +020068 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010069
Marcel Holtmanna9de9242007-10-20 13:33:56 +020070 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070071}
72
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020075 __u8 status = *((__u8 *) skb->data);
76
77 BT_DBG("%s status 0x%x", hdev->name, status);
78
79 if (status)
80 return;
81
Marcel Holtmanna9de9242007-10-20 13:33:56 +020082 hci_conn_check_pending(hdev);
83}
84
85static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
86{
87 BT_DBG("%s", hdev->name);
88}
89
90static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
91{
92 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 if (rp->status)
98 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200102 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
103 if (conn) {
104 if (rp->role)
105 conn->link_mode &= ~HCI_LM_MASTER;
106 else
107 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200109
110 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111}
112
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200113static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
114{
115 struct hci_rp_read_link_policy *rp = (void *) skb->data;
116 struct hci_conn *conn;
117
118 BT_DBG("%s status 0x%x", hdev->name, rp->status);
119
120 if (rp->status)
121 return;
122
123 hci_dev_lock(hdev);
124
125 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
126 if (conn)
127 conn->link_policy = __le16_to_cpu(rp->policy);
128
129 hci_dev_unlock(hdev);
130}
131
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200132static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200134 struct hci_rp_write_link_policy *rp = (void *) skb->data;
135 struct hci_conn *conn;
136 void *sent;
137
138 BT_DBG("%s status 0x%x", hdev->name, rp->status);
139
140 if (rp->status)
141 return;
142
143 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
144 if (!sent)
145 return;
146
147 hci_dev_lock(hdev);
148
149 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200150 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700151 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200152
153 hci_dev_unlock(hdev);
154}
155
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200156static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
157{
158 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
159
160 BT_DBG("%s status 0x%x", hdev->name, rp->status);
161
162 if (rp->status)
163 return;
164
165 hdev->link_policy = __le16_to_cpu(rp->policy);
166}
167
168static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
169{
170 __u8 status = *((__u8 *) skb->data);
171 void *sent;
172
173 BT_DBG("%s status 0x%x", hdev->name, status);
174
175 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
176 if (!sent)
177 return;
178
179 if (!status)
180 hdev->link_policy = get_unaligned_le16(sent);
181
Johan Hedberg23bb5762010-12-21 23:01:27 +0200182 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200183}
184
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200185static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
186{
187 __u8 status = *((__u8 *) skb->data);
188
189 BT_DBG("%s status 0x%x", hdev->name, status);
190
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300191 clear_bit(HCI_RESET, &hdev->flags);
192
Johan Hedberg23bb5762010-12-21 23:01:27 +0200193 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300194
Johan Hedberga297e972012-02-21 17:55:47 +0200195 /* Reset all non-persistent flags */
196 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN));
Andre Guedes69775ff2012-02-23 16:50:05 +0200197
198 hdev->discovery.state = DISCOVERY_STOPPED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200199}
200
201static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
202{
203 __u8 status = *((__u8 *) skb->data);
204 void *sent;
205
206 BT_DBG("%s status 0x%x", hdev->name, status);
207
208 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
209 if (!sent)
210 return;
211
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200212 hci_dev_lock(hdev);
213
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200214 if (test_bit(HCI_MGMT, &hdev->dev_flags))
215 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200216 else if (!status)
217 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200218
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200219 hci_dev_unlock(hdev);
Johan Hedberg3159d382012-02-24 13:47:56 +0200220
221 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200222}
223
224static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
225{
226 struct hci_rp_read_local_name *rp = (void *) skb->data;
227
228 BT_DBG("%s status 0x%x", hdev->name, rp->status);
229
230 if (rp->status)
231 return;
232
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200233 if (test_bit(HCI_SETUP, &hdev->dev_flags))
234 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200235}
236
237static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
238{
239 __u8 status = *((__u8 *) skb->data);
240 void *sent;
241
242 BT_DBG("%s status 0x%x", hdev->name, status);
243
244 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
245 if (!sent)
246 return;
247
248 if (!status) {
249 __u8 param = *((__u8 *) sent);
250
251 if (param == AUTH_ENABLED)
252 set_bit(HCI_AUTH, &hdev->flags);
253 else
254 clear_bit(HCI_AUTH, &hdev->flags);
255 }
256
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200257 if (test_bit(HCI_MGMT, &hdev->dev_flags))
258 mgmt_auth_enable_complete(hdev, status);
259
Johan Hedberg23bb5762010-12-21 23:01:27 +0200260 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200261}
262
263static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
264{
265 __u8 status = *((__u8 *) skb->data);
266 void *sent;
267
268 BT_DBG("%s status 0x%x", hdev->name, status);
269
270 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
271 if (!sent)
272 return;
273
274 if (!status) {
275 __u8 param = *((__u8 *) sent);
276
277 if (param)
278 set_bit(HCI_ENCRYPT, &hdev->flags);
279 else
280 clear_bit(HCI_ENCRYPT, &hdev->flags);
281 }
282
Johan Hedberg23bb5762010-12-21 23:01:27 +0200283 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200284}
285
286static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
287{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200288 __u8 param, status = *((__u8 *) skb->data);
289 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200290 void *sent;
291
292 BT_DBG("%s status 0x%x", hdev->name, status);
293
294 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
295 if (!sent)
296 return;
297
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200298 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200299
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200300 hci_dev_lock(hdev);
301
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200302 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200303 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200304 hdev->discov_timeout = 0;
305 goto done;
306 }
307
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200308 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
309 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200310
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200311 if (param & SCAN_INQUIRY) {
312 set_bit(HCI_ISCAN, &hdev->flags);
313 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200314 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200315 if (hdev->discov_timeout > 0) {
316 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
317 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
318 to);
319 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200320 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200321 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200322
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 if (param & SCAN_PAGE) {
324 set_bit(HCI_PSCAN, &hdev->flags);
325 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200328 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200329
330done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200331 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200332 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200333}
334
335static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
336{
337 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
338
339 BT_DBG("%s status 0x%x", hdev->name, rp->status);
340
341 if (rp->status)
342 return;
343
344 memcpy(hdev->dev_class, rp->dev_class, 3);
345
346 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
347 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
348}
349
350static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
351{
352 __u8 status = *((__u8 *) skb->data);
353 void *sent;
354
355 BT_DBG("%s status 0x%x", hdev->name, status);
356
357 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
358 if (!sent)
359 return;
360
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100361 hci_dev_lock(hdev);
362
363 if (status == 0)
364 memcpy(hdev->dev_class, sent, 3);
365
366 if (test_bit(HCI_MGMT, &hdev->dev_flags))
367 mgmt_set_class_of_dev_complete(hdev, sent, status);
368
369 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200370}
371
372static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
373{
374 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200376
377 BT_DBG("%s status 0x%x", hdev->name, rp->status);
378
379 if (rp->status)
380 return;
381
382 setting = __le16_to_cpu(rp->voice_setting);
383
Marcel Holtmannf383f272008-07-14 20:13:47 +0200384 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200385 return;
386
387 hdev->voice_setting = setting;
388
389 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
390
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200391 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200393}
394
395static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
396{
397 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200398 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 void *sent;
400
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200401 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Marcel Holtmannf383f272008-07-14 20:13:47 +0200403 if (status)
404 return;
405
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200406 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
407 if (!sent)
408 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Marcel Holtmannf383f272008-07-14 20:13:47 +0200412 if (hdev->voice_setting == setting)
413 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Marcel Holtmannf383f272008-07-14 20:13:47 +0200415 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Marcel Holtmannf383f272008-07-14 20:13:47 +0200417 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
418
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200419 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200420 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421}
422
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200423static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200425 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200427 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428
Johan Hedberg23bb5762010-12-21 23:01:27 +0200429 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430}
431
Marcel Holtmann333140b2008-07-14 20:13:48 +0200432static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
433{
434 __u8 status = *((__u8 *) skb->data);
435 void *sent;
436
437 BT_DBG("%s status 0x%x", hdev->name, status);
438
Marcel Holtmann333140b2008-07-14 20:13:48 +0200439 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
440 if (!sent)
441 return;
442
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200443 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200444 mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status);
445 else if (!status) {
446 if (*((u8 *) sent))
447 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
448 else
449 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
450 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200451}
452
Johan Hedbergd5859e22011-01-25 01:19:58 +0200453static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
454{
455 if (hdev->features[6] & LMP_EXT_INQ)
456 return 2;
457
458 if (hdev->features[3] & LMP_RSSI_INQ)
459 return 1;
460
461 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
462 hdev->lmp_subver == 0x0757)
463 return 1;
464
465 if (hdev->manufacturer == 15) {
466 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
467 return 1;
468 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
469 return 1;
470 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
471 return 1;
472 }
473
474 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
475 hdev->lmp_subver == 0x1805)
476 return 1;
477
478 return 0;
479}
480
481static void hci_setup_inquiry_mode(struct hci_dev *hdev)
482{
483 u8 mode;
484
485 mode = hci_get_inquiry_mode(hdev);
486
487 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
488}
489
490static void hci_setup_event_mask(struct hci_dev *hdev)
491{
492 /* The second byte is 0xff instead of 0x9f (two reserved bits
493 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
494 * command otherwise */
495 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
496
Ville Tervo6de6c182011-05-27 11:16:21 +0300497 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
498 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200499 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300500 return;
501
502 events[4] |= 0x01; /* Flow Specification Complete */
503 events[4] |= 0x02; /* Inquiry Result with RSSI */
504 events[4] |= 0x04; /* Read Remote Extended Features Complete */
505 events[5] |= 0x08; /* Synchronous Connection Complete */
506 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200507
508 if (hdev->features[3] & LMP_RSSI_INQ)
509 events[4] |= 0x04; /* Inquiry Result with RSSI */
510
511 if (hdev->features[5] & LMP_SNIFF_SUBR)
512 events[5] |= 0x20; /* Sniff Subrating */
513
514 if (hdev->features[5] & LMP_PAUSE_ENC)
515 events[5] |= 0x80; /* Encryption Key Refresh Complete */
516
517 if (hdev->features[6] & LMP_EXT_INQ)
518 events[5] |= 0x40; /* Extended Inquiry Result */
519
520 if (hdev->features[6] & LMP_NO_FLUSH)
521 events[7] |= 0x01; /* Enhanced Flush Complete */
522
523 if (hdev->features[7] & LMP_LSTO)
524 events[6] |= 0x80; /* Link Supervision Timeout Changed */
525
526 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
527 events[6] |= 0x01; /* IO Capability Request */
528 events[6] |= 0x02; /* IO Capability Response */
529 events[6] |= 0x04; /* User Confirmation Request */
530 events[6] |= 0x08; /* User Passkey Request */
531 events[6] |= 0x10; /* Remote OOB Data Request */
532 events[6] |= 0x20; /* Simple Pairing Complete */
533 events[7] |= 0x04; /* User Passkey Notification */
534 events[7] |= 0x08; /* Keypress Notification */
535 events[7] |= 0x10; /* Remote Host Supported
536 * Features Notification */
537 }
538
539 if (hdev->features[4] & LMP_LE)
540 events[7] |= 0x20; /* LE Meta-Event */
541
542 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
543}
544
Andre Guedese6100a22011-06-30 19:20:54 -0300545static void hci_set_le_support(struct hci_dev *hdev)
546{
547 struct hci_cp_write_le_host_supported cp;
548
549 memset(&cp, 0, sizeof(cp));
550
Johan Hedberg06199cf2012-02-22 16:37:11 +0200551 if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
Andre Guedese6100a22011-06-30 19:20:54 -0300552 cp.le = 1;
553 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
554 }
555
556 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
557}
558
Johan Hedbergd5859e22011-01-25 01:19:58 +0200559static void hci_setup(struct hci_dev *hdev)
560{
Andrei Emeltchenkoe61ef492011-12-19 16:31:27 +0200561 if (hdev->dev_type != HCI_BREDR)
562 return;
563
Johan Hedbergd5859e22011-01-25 01:19:58 +0200564 hci_setup_event_mask(hdev);
565
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200566 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200567 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
568
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200569 if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
570 test_bit(HCI_MGMT, &hdev->dev_flags)) {
571 struct hci_cp_write_local_name cp;
572
573 memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
574 hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp);
575 }
576
Johan Hedberg54d04db2012-02-22 15:47:48 +0200577 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
578 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
579 u8 mode = 0x01;
580 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
581 sizeof(mode), &mode);
582 } else {
583 struct hci_cp_write_eir cp;
584
585 memset(hdev->eir, 0, sizeof(hdev->eir));
586 memset(&cp, 0, sizeof(cp));
587
588 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
589 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200590 }
591
592 if (hdev->features[3] & LMP_RSSI_INQ)
593 hci_setup_inquiry_mode(hdev);
594
595 if (hdev->features[7] & LMP_INQ_TX_PWR)
596 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300597
598 if (hdev->features[7] & LMP_EXTFEATURES) {
599 struct hci_cp_read_local_ext_features cp;
600
601 cp.page = 0x01;
602 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
603 sizeof(cp), &cp);
604 }
Andre Guedese6100a22011-06-30 19:20:54 -0300605
Johan Hedberg47990ea2012-02-22 11:58:37 +0200606 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
607 u8 enable = 1;
608 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE,
609 sizeof(enable), &enable);
610 }
611
Andre Guedese6100a22011-06-30 19:20:54 -0300612 if (hdev->features[4] & LMP_LE)
613 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200614}
615
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200616static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
617{
618 struct hci_rp_read_local_version *rp = (void *) skb->data;
619
620 BT_DBG("%s status 0x%x", hdev->name, rp->status);
621
622 if (rp->status)
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200623 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200624
625 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200626 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200627 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200628 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200629 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200630
631 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
632 hdev->manufacturer,
633 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200634
635 if (test_bit(HCI_INIT, &hdev->flags))
636 hci_setup(hdev);
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200637
638done:
639 hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200640}
641
642static void hci_setup_link_policy(struct hci_dev *hdev)
643{
644 u16 link_policy = 0;
645
646 if (hdev->features[0] & LMP_RSWITCH)
647 link_policy |= HCI_LP_RSWITCH;
648 if (hdev->features[0] & LMP_HOLD)
649 link_policy |= HCI_LP_HOLD;
650 if (hdev->features[0] & LMP_SNIFF)
651 link_policy |= HCI_LP_SNIFF;
652 if (hdev->features[1] & LMP_PARK)
653 link_policy |= HCI_LP_PARK;
654
655 link_policy = cpu_to_le16(link_policy);
656 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
657 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200658}
659
660static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
661{
662 struct hci_rp_read_local_commands *rp = (void *) skb->data;
663
664 BT_DBG("%s status 0x%x", hdev->name, rp->status);
665
666 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200667 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200668
669 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200670
671 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
672 hci_setup_link_policy(hdev);
673
674done:
675 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200676}
677
678static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
679{
680 struct hci_rp_read_local_features *rp = (void *) skb->data;
681
682 BT_DBG("%s status 0x%x", hdev->name, rp->status);
683
684 if (rp->status)
685 return;
686
687 memcpy(hdev->features, rp->features, 8);
688
689 /* Adjust default settings according to features
690 * supported by device. */
691
692 if (hdev->features[0] & LMP_3SLOT)
693 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
694
695 if (hdev->features[0] & LMP_5SLOT)
696 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
697
698 if (hdev->features[1] & LMP_HV2) {
699 hdev->pkt_type |= (HCI_HV2);
700 hdev->esco_type |= (ESCO_HV2);
701 }
702
703 if (hdev->features[1] & LMP_HV3) {
704 hdev->pkt_type |= (HCI_HV3);
705 hdev->esco_type |= (ESCO_HV3);
706 }
707
708 if (hdev->features[3] & LMP_ESCO)
709 hdev->esco_type |= (ESCO_EV3);
710
711 if (hdev->features[4] & LMP_EV4)
712 hdev->esco_type |= (ESCO_EV4);
713
714 if (hdev->features[4] & LMP_EV5)
715 hdev->esco_type |= (ESCO_EV5);
716
Marcel Holtmannefc76882009-02-06 09:13:37 +0100717 if (hdev->features[5] & LMP_EDR_ESCO_2M)
718 hdev->esco_type |= (ESCO_2EV3);
719
720 if (hdev->features[5] & LMP_EDR_ESCO_3M)
721 hdev->esco_type |= (ESCO_3EV3);
722
723 if (hdev->features[5] & LMP_EDR_3S_ESCO)
724 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
725
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200726 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
727 hdev->features[0], hdev->features[1],
728 hdev->features[2], hdev->features[3],
729 hdev->features[4], hdev->features[5],
730 hdev->features[6], hdev->features[7]);
731}
732
Andre Guedes971e3a42011-06-30 19:20:52 -0300733static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
734 struct sk_buff *skb)
735{
736 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
737
738 BT_DBG("%s status 0x%x", hdev->name, rp->status);
739
740 if (rp->status)
741 return;
742
Andre Guedesb5b32b62011-12-30 10:34:04 -0300743 switch (rp->page) {
744 case 0:
745 memcpy(hdev->features, rp->features, 8);
746 break;
747 case 1:
748 memcpy(hdev->host_features, rp->features, 8);
749 break;
750 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300751
752 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
753}
754
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200755static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
756 struct sk_buff *skb)
757{
758 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
759
760 BT_DBG("%s status 0x%x", hdev->name, rp->status);
761
762 if (rp->status)
763 return;
764
765 hdev->flow_ctl_mode = rp->mode;
766
767 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
768}
769
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200770static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
771{
772 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
773
774 BT_DBG("%s status 0x%x", hdev->name, rp->status);
775
776 if (rp->status)
777 return;
778
779 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
780 hdev->sco_mtu = rp->sco_mtu;
781 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
782 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
783
784 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
785 hdev->sco_mtu = 64;
786 hdev->sco_pkts = 8;
787 }
788
789 hdev->acl_cnt = hdev->acl_pkts;
790 hdev->sco_cnt = hdev->sco_pkts;
791
792 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
793 hdev->acl_mtu, hdev->acl_pkts,
794 hdev->sco_mtu, hdev->sco_pkts);
795}
796
797static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
798{
799 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
800
801 BT_DBG("%s status 0x%x", hdev->name, rp->status);
802
803 if (!rp->status)
804 bacpy(&hdev->bdaddr, &rp->bdaddr);
805
Johan Hedberg23bb5762010-12-21 23:01:27 +0200806 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
807}
808
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200809static void hci_cc_read_data_block_size(struct hci_dev *hdev,
810 struct sk_buff *skb)
811{
812 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
813
814 BT_DBG("%s status 0x%x", hdev->name, rp->status);
815
816 if (rp->status)
817 return;
818
819 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
820 hdev->block_len = __le16_to_cpu(rp->block_len);
821 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
822
823 hdev->block_cnt = hdev->num_blocks;
824
825 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
826 hdev->block_cnt, hdev->block_len);
827
828 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
829}
830
Johan Hedberg23bb5762010-12-21 23:01:27 +0200831static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
832{
833 __u8 status = *((__u8 *) skb->data);
834
835 BT_DBG("%s status 0x%x", hdev->name, status);
836
837 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200838}
839
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300840static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
841 struct sk_buff *skb)
842{
843 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
844
845 BT_DBG("%s status 0x%x", hdev->name, rp->status);
846
847 if (rp->status)
848 return;
849
850 hdev->amp_status = rp->amp_status;
851 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
852 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
853 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
854 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
855 hdev->amp_type = rp->amp_type;
856 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
857 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
858 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
859 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
860
861 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
862}
863
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200864static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
865 struct sk_buff *skb)
866{
867 __u8 status = *((__u8 *) skb->data);
868
869 BT_DBG("%s status 0x%x", hdev->name, status);
870
871 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
872}
873
Johan Hedbergd5859e22011-01-25 01:19:58 +0200874static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
875{
876 __u8 status = *((__u8 *) skb->data);
877
878 BT_DBG("%s status 0x%x", hdev->name, status);
879
880 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
881}
882
883static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
884 struct sk_buff *skb)
885{
886 __u8 status = *((__u8 *) skb->data);
887
888 BT_DBG("%s status 0x%x", hdev->name, status);
889
890 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
891}
892
893static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
894 struct sk_buff *skb)
895{
896 __u8 status = *((__u8 *) skb->data);
897
898 BT_DBG("%s status 0x%x", hdev->name, status);
899
900 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
901}
902
903static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
904{
905 __u8 status = *((__u8 *) skb->data);
906
907 BT_DBG("%s status 0x%x", hdev->name, status);
908
909 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
910}
911
Johan Hedberg980e1a52011-01-22 06:10:07 +0200912static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
913{
914 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
915 struct hci_cp_pin_code_reply *cp;
916 struct hci_conn *conn;
917
918 BT_DBG("%s status 0x%x", hdev->name, rp->status);
919
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200920 hci_dev_lock(hdev);
921
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200922 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200923 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200924
925 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200926 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200927
928 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
929 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200930 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200931
932 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
933 if (conn)
934 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200935
936unlock:
937 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200938}
939
940static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
941{
942 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
943
944 BT_DBG("%s status 0x%x", hdev->name, rp->status);
945
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200946 hci_dev_lock(hdev);
947
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200948 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200949 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200950 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200951
952 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200953}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200954
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300955static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
956 struct sk_buff *skb)
957{
958 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
959
960 BT_DBG("%s status 0x%x", hdev->name, rp->status);
961
962 if (rp->status)
963 return;
964
965 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
966 hdev->le_pkts = rp->le_max_pkt;
967
968 hdev->le_cnt = hdev->le_pkts;
969
970 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
971
972 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
973}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200974
Johan Hedberga5c29682011-02-19 12:05:57 -0300975static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
976{
977 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
978
979 BT_DBG("%s status 0x%x", hdev->name, rp->status);
980
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200981 hci_dev_lock(hdev);
982
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200983 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200984 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
985 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200986
987 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300988}
989
990static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
991 struct sk_buff *skb)
992{
993 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
994
995 BT_DBG("%s status 0x%x", hdev->name, rp->status);
996
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200997 hci_dev_lock(hdev);
998
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200999 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001000 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001001 ACL_LINK, 0,
Johan Hedberga5c29682011-02-19 12:05:57 -03001002 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001003
1004 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -03001005}
1006
Brian Gix1143d452011-11-23 08:28:34 -08001007static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
1008{
1009 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1010
1011 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1012
1013 hci_dev_lock(hdev);
1014
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001015 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001016 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1017 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001018
1019 hci_dev_unlock(hdev);
1020}
1021
1022static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1023 struct sk_buff *skb)
1024{
1025 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1026
1027 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1028
1029 hci_dev_lock(hdev);
1030
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001031 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001032 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001033 ACL_LINK, 0,
Brian Gix1143d452011-11-23 08:28:34 -08001034 rp->status);
1035
1036 hci_dev_unlock(hdev);
1037}
1038
Szymon Jancc35938b2011-03-22 13:12:21 +01001039static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1040 struct sk_buff *skb)
1041{
1042 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1043
1044 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1045
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001046 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001047 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001048 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001049 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001050}
1051
Andre Guedes07f7fa52011-12-02 21:13:31 +09001052static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1053{
1054 __u8 status = *((__u8 *) skb->data);
1055
1056 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001057
1058 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001059
1060 if (status) {
1061 hci_dev_lock(hdev);
1062 mgmt_start_discovery_failed(hdev, status);
1063 hci_dev_unlock(hdev);
1064 return;
1065 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001066}
1067
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001068static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1069 struct sk_buff *skb)
1070{
1071 struct hci_cp_le_set_scan_enable *cp;
1072 __u8 status = *((__u8 *) skb->data);
1073
1074 BT_DBG("%s status 0x%x", hdev->name, status);
1075
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001076 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1077 if (!cp)
1078 return;
1079
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001080 switch (cp->enable) {
1081 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001082 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1083
Andre Guedes3fd24152012-02-03 17:48:01 -03001084 if (status) {
1085 hci_dev_lock(hdev);
1086 mgmt_start_discovery_failed(hdev, status);
1087 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001088 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001089 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001090
Andre Guedesd23264a2011-11-25 20:53:38 -03001091 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1092
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001093 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001094
1095 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001096 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001097 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001098 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001099 break;
1100
1101 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001102 if (status)
1103 return;
1104
Andre Guedesd23264a2011-11-25 20:53:38 -03001105 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1106
Andre Guedesd0843292012-01-02 19:18:11 -03001107 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001108
1109 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1110 mgmt_interleaved_discovery(hdev);
1111 } else {
1112 hci_dev_lock(hdev);
1113 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1114 hci_dev_unlock(hdev);
1115 }
1116
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001117 break;
1118
1119 default:
1120 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1121 break;
Andre Guedes35815082011-05-26 16:23:53 -03001122 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001123}
1124
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001125static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1126{
1127 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1128
1129 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1130
1131 if (rp->status)
1132 return;
1133
1134 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1135}
1136
1137static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1138{
1139 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1140
1141 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1142
1143 if (rp->status)
1144 return;
1145
1146 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1147}
1148
Andre Guedesf9b49302011-06-30 19:20:53 -03001149static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1150 struct sk_buff *skb)
1151{
1152 struct hci_cp_read_local_ext_features cp;
Johan Hedberg06199cf2012-02-22 16:37:11 +02001153 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001154 __u8 status = *((__u8 *) skb->data);
1155
1156 BT_DBG("%s status 0x%x", hdev->name, status);
1157
Johan Hedberg06199cf2012-02-22 16:37:11 +02001158 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
1159 if (sent && test_bit(HCI_MGMT, &hdev->dev_flags))
1160 mgmt_le_enable_complete(hdev, sent->le, status);
1161
Andre Guedesf9b49302011-06-30 19:20:53 -03001162 if (status)
1163 return;
1164
1165 cp.page = 0x01;
1166 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1167}
1168
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001169static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1170{
1171 BT_DBG("%s status 0x%x", hdev->name, status);
1172
1173 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001174 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001175 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001176 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001177 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001178 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001179 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001180 return;
1181 }
1182
Andre Guedes89352e72011-11-04 14:16:53 -03001183 set_bit(HCI_INQUIRY, &hdev->flags);
1184
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001185 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001186 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001187 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001188}
1189
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1191{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001192 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001195 BT_DBG("%s status 0x%x", hdev->name, status);
1196
1197 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 if (!cp)
1199 return;
1200
1201 hci_dev_lock(hdev);
1202
1203 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1204
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001205 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206
1207 if (status) {
1208 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001209 if (status != 0x0c || conn->attempt > 2) {
1210 conn->state = BT_CLOSED;
1211 hci_proto_connect_cfm(conn, status);
1212 hci_conn_del(conn);
1213 } else
1214 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 }
1216 } else {
1217 if (!conn) {
1218 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1219 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001220 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 conn->link_mode |= HCI_LM_MASTER;
1222 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001223 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 }
1225 }
1226
1227 hci_dev_unlock(hdev);
1228}
1229
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001230static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001232 struct hci_cp_add_sco *cp;
1233 struct hci_conn *acl, *sco;
1234 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001236 BT_DBG("%s status 0x%x", hdev->name, status);
1237
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001238 if (!status)
1239 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001241 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1242 if (!cp)
1243 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001245 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001247 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001248
1249 hci_dev_lock(hdev);
1250
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001251 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001252 if (acl) {
1253 sco = acl->link;
1254 if (sco) {
1255 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001256
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001257 hci_proto_connect_cfm(sco, status);
1258 hci_conn_del(sco);
1259 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001260 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001261
1262 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263}
1264
Marcel Holtmannf8558552008-07-14 20:13:49 +02001265static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1266{
1267 struct hci_cp_auth_requested *cp;
1268 struct hci_conn *conn;
1269
1270 BT_DBG("%s status 0x%x", hdev->name, status);
1271
1272 if (!status)
1273 return;
1274
1275 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1276 if (!cp)
1277 return;
1278
1279 hci_dev_lock(hdev);
1280
1281 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1282 if (conn) {
1283 if (conn->state == BT_CONFIG) {
1284 hci_proto_connect_cfm(conn, status);
1285 hci_conn_put(conn);
1286 }
1287 }
1288
1289 hci_dev_unlock(hdev);
1290}
1291
1292static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1293{
1294 struct hci_cp_set_conn_encrypt *cp;
1295 struct hci_conn *conn;
1296
1297 BT_DBG("%s status 0x%x", hdev->name, status);
1298
1299 if (!status)
1300 return;
1301
1302 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1303 if (!cp)
1304 return;
1305
1306 hci_dev_lock(hdev);
1307
1308 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1309 if (conn) {
1310 if (conn->state == BT_CONFIG) {
1311 hci_proto_connect_cfm(conn, status);
1312 hci_conn_put(conn);
1313 }
1314 }
1315
1316 hci_dev_unlock(hdev);
1317}
1318
Johan Hedberg127178d2010-11-18 22:22:29 +02001319static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001320 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001321{
Johan Hedberg392599b2010-11-18 22:22:28 +02001322 if (conn->state != BT_CONFIG || !conn->out)
1323 return 0;
1324
Johan Hedberg765c2a92011-01-19 12:06:52 +05301325 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001326 return 0;
1327
1328 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001329 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001330 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001331 conn->pending_sec_level != BT_SECURITY_HIGH &&
1332 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001333 return 0;
1334
Johan Hedberg392599b2010-11-18 22:22:28 +02001335 return 1;
1336}
1337
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001338static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1339{
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,
1370 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1371{
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))
Johan Hedberg08c79b62012-02-23 22:31:51 +02001376 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0,
Johan Hedbergb644ba32012-01-17 21:48:47 +02001377 name, name_len, conn->dev_class);
1378
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,
1394 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,
1603 conn->dst_type, status);
1604
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,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001719 info->dev_class, 0, !name_known, ssp,
Andre Guedes7d262f82012-01-10 18:20:49 -03001720 NULL, 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,
1771 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);
1779 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1780 sizeof(cp), &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,
Johan Hedberg48264f02011-11-09 13:58:58 +02001786 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
1851 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1852 sizeof(cp), &cp);
1853 } 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,
1866 sizeof(cp), &cp);
1867 }
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,
Johan Hedberg48264f02011-11-09 13:58:58 +02001901 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) {
1905 hci_proto_disconn_cfm(conn, ev->reason);
1906 hci_conn_del(conn);
1907 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001908
1909unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910 hci_dev_unlock(hdev);
1911}
1912
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001913static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1914{
1915 struct hci_ev_auth_complete *ev = (void *) skb->data;
1916 struct hci_conn *conn;
1917
1918 BT_DBG("%s status %d", hdev->name, ev->status);
1919
1920 hci_dev_lock(hdev);
1921
1922 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001923 if (!conn)
1924 goto unlock;
1925
1926 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001927 if (!hci_conn_ssp_enabled(conn) &&
1928 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001929 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001930 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001931 conn->link_mode |= HCI_LM_AUTH;
1932 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001933 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001934 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001935 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
1936 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001937 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001938
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001939 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1940 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001941
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001942 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001943 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001944 struct hci_cp_set_conn_encrypt cp;
1945 cp.handle = ev->handle;
1946 cp.encrypt = 0x01;
1947 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1948 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001949 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001950 conn->state = BT_CONNECTED;
1951 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001952 hci_conn_put(conn);
1953 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001954 } else {
1955 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001956
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001957 hci_conn_hold(conn);
1958 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1959 hci_conn_put(conn);
1960 }
1961
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001962 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001963 if (!ev->status) {
1964 struct hci_cp_set_conn_encrypt cp;
1965 cp.handle = ev->handle;
1966 cp.encrypt = 0x01;
1967 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1968 &cp);
1969 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001970 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001971 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001972 }
1973 }
1974
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001975unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001976 hci_dev_unlock(hdev);
1977}
1978
1979static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1980{
Johan Hedberg127178d2010-11-18 22:22:29 +02001981 struct hci_ev_remote_name *ev = (void *) skb->data;
1982 struct hci_conn *conn;
1983
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001984 BT_DBG("%s", hdev->name);
1985
1986 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001987
1988 hci_dev_lock(hdev);
1989
1990 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001991
1992 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1993 goto check_auth;
1994
1995 if (ev->status == 0)
1996 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1997 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1998 else
1999 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2000
2001check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002002 if (!conn)
2003 goto unlock;
2004
2005 if (!hci_outgoing_auth_needed(hdev, conn))
2006 goto unlock;
2007
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002008 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002009 struct hci_cp_auth_requested cp;
2010 cp.handle = __cpu_to_le16(conn->handle);
2011 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2012 }
2013
Johan Hedberg79c6c702011-04-28 11:28:55 -07002014unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002015 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002016}
2017
2018static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2019{
2020 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2021 struct hci_conn *conn;
2022
2023 BT_DBG("%s status %d", hdev->name, ev->status);
2024
2025 hci_dev_lock(hdev);
2026
2027 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2028 if (conn) {
2029 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002030 if (ev->encrypt) {
2031 /* Encryption implies authentication */
2032 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002033 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002034 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002035 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002036 conn->link_mode &= ~HCI_LM_ENCRYPT;
2037 }
2038
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002039 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002040
Marcel Holtmannf8558552008-07-14 20:13:49 +02002041 if (conn->state == BT_CONFIG) {
2042 if (!ev->status)
2043 conn->state = BT_CONNECTED;
2044
2045 hci_proto_connect_cfm(conn, ev->status);
2046 hci_conn_put(conn);
2047 } else
2048 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002049 }
2050
2051 hci_dev_unlock(hdev);
2052}
2053
2054static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2055{
2056 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2057 struct hci_conn *conn;
2058
2059 BT_DBG("%s status %d", hdev->name, ev->status);
2060
2061 hci_dev_lock(hdev);
2062
2063 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2064 if (conn) {
2065 if (!ev->status)
2066 conn->link_mode |= HCI_LM_SECURE;
2067
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002068 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002069
2070 hci_key_change_cfm(conn, ev->status);
2071 }
2072
2073 hci_dev_unlock(hdev);
2074}
2075
2076static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2077{
2078 struct hci_ev_remote_features *ev = (void *) skb->data;
2079 struct hci_conn *conn;
2080
2081 BT_DBG("%s status %d", hdev->name, ev->status);
2082
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002083 hci_dev_lock(hdev);
2084
2085 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002086 if (!conn)
2087 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002088
Johan Hedbergccd556f2010-11-10 17:11:51 +02002089 if (!ev->status)
2090 memcpy(conn->features, ev->features, 8);
2091
2092 if (conn->state != BT_CONFIG)
2093 goto unlock;
2094
2095 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2096 struct hci_cp_read_remote_ext_features cp;
2097 cp.handle = ev->handle;
2098 cp.page = 0x01;
2099 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002100 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002101 goto unlock;
2102 }
2103
Johan Hedberg127178d2010-11-18 22:22:29 +02002104 if (!ev->status) {
2105 struct hci_cp_remote_name_req cp;
2106 memset(&cp, 0, sizeof(cp));
2107 bacpy(&cp.bdaddr, &conn->dst);
2108 cp.pscan_rep_mode = 0x02;
2109 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002110 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2111 mgmt_device_connected(hdev, &conn->dst, conn->type,
Johan Hedberg08c79b62012-02-23 22:31:51 +02002112 conn->dst_type, 0, NULL, 0,
Johan Hedbergb644ba32012-01-17 21:48:47 +02002113 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002114
Johan Hedberg127178d2010-11-18 22:22:29 +02002115 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002116 conn->state = BT_CONNECTED;
2117 hci_proto_connect_cfm(conn, ev->status);
2118 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002119 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002120
Johan Hedbergccd556f2010-11-10 17:11:51 +02002121unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002122 hci_dev_unlock(hdev);
2123}
2124
2125static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2126{
2127 BT_DBG("%s", hdev->name);
2128}
2129
2130static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2131{
2132 BT_DBG("%s", hdev->name);
2133}
2134
2135static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2136{
2137 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2138 __u16 opcode;
2139
2140 skb_pull(skb, sizeof(*ev));
2141
2142 opcode = __le16_to_cpu(ev->opcode);
2143
2144 switch (opcode) {
2145 case HCI_OP_INQUIRY_CANCEL:
2146 hci_cc_inquiry_cancel(hdev, skb);
2147 break;
2148
2149 case HCI_OP_EXIT_PERIODIC_INQ:
2150 hci_cc_exit_periodic_inq(hdev, skb);
2151 break;
2152
2153 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2154 hci_cc_remote_name_req_cancel(hdev, skb);
2155 break;
2156
2157 case HCI_OP_ROLE_DISCOVERY:
2158 hci_cc_role_discovery(hdev, skb);
2159 break;
2160
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002161 case HCI_OP_READ_LINK_POLICY:
2162 hci_cc_read_link_policy(hdev, skb);
2163 break;
2164
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002165 case HCI_OP_WRITE_LINK_POLICY:
2166 hci_cc_write_link_policy(hdev, skb);
2167 break;
2168
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002169 case HCI_OP_READ_DEF_LINK_POLICY:
2170 hci_cc_read_def_link_policy(hdev, skb);
2171 break;
2172
2173 case HCI_OP_WRITE_DEF_LINK_POLICY:
2174 hci_cc_write_def_link_policy(hdev, skb);
2175 break;
2176
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002177 case HCI_OP_RESET:
2178 hci_cc_reset(hdev, skb);
2179 break;
2180
2181 case HCI_OP_WRITE_LOCAL_NAME:
2182 hci_cc_write_local_name(hdev, skb);
2183 break;
2184
2185 case HCI_OP_READ_LOCAL_NAME:
2186 hci_cc_read_local_name(hdev, skb);
2187 break;
2188
2189 case HCI_OP_WRITE_AUTH_ENABLE:
2190 hci_cc_write_auth_enable(hdev, skb);
2191 break;
2192
2193 case HCI_OP_WRITE_ENCRYPT_MODE:
2194 hci_cc_write_encrypt_mode(hdev, skb);
2195 break;
2196
2197 case HCI_OP_WRITE_SCAN_ENABLE:
2198 hci_cc_write_scan_enable(hdev, skb);
2199 break;
2200
2201 case HCI_OP_READ_CLASS_OF_DEV:
2202 hci_cc_read_class_of_dev(hdev, skb);
2203 break;
2204
2205 case HCI_OP_WRITE_CLASS_OF_DEV:
2206 hci_cc_write_class_of_dev(hdev, skb);
2207 break;
2208
2209 case HCI_OP_READ_VOICE_SETTING:
2210 hci_cc_read_voice_setting(hdev, skb);
2211 break;
2212
2213 case HCI_OP_WRITE_VOICE_SETTING:
2214 hci_cc_write_voice_setting(hdev, skb);
2215 break;
2216
2217 case HCI_OP_HOST_BUFFER_SIZE:
2218 hci_cc_host_buffer_size(hdev, skb);
2219 break;
2220
Marcel Holtmann333140b2008-07-14 20:13:48 +02002221 case HCI_OP_WRITE_SSP_MODE:
2222 hci_cc_write_ssp_mode(hdev, skb);
2223 break;
2224
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002225 case HCI_OP_READ_LOCAL_VERSION:
2226 hci_cc_read_local_version(hdev, skb);
2227 break;
2228
2229 case HCI_OP_READ_LOCAL_COMMANDS:
2230 hci_cc_read_local_commands(hdev, skb);
2231 break;
2232
2233 case HCI_OP_READ_LOCAL_FEATURES:
2234 hci_cc_read_local_features(hdev, skb);
2235 break;
2236
Andre Guedes971e3a42011-06-30 19:20:52 -03002237 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2238 hci_cc_read_local_ext_features(hdev, skb);
2239 break;
2240
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002241 case HCI_OP_READ_BUFFER_SIZE:
2242 hci_cc_read_buffer_size(hdev, skb);
2243 break;
2244
2245 case HCI_OP_READ_BD_ADDR:
2246 hci_cc_read_bd_addr(hdev, skb);
2247 break;
2248
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002249 case HCI_OP_READ_DATA_BLOCK_SIZE:
2250 hci_cc_read_data_block_size(hdev, skb);
2251 break;
2252
Johan Hedberg23bb5762010-12-21 23:01:27 +02002253 case HCI_OP_WRITE_CA_TIMEOUT:
2254 hci_cc_write_ca_timeout(hdev, skb);
2255 break;
2256
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002257 case HCI_OP_READ_FLOW_CONTROL_MODE:
2258 hci_cc_read_flow_control_mode(hdev, skb);
2259 break;
2260
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002261 case HCI_OP_READ_LOCAL_AMP_INFO:
2262 hci_cc_read_local_amp_info(hdev, skb);
2263 break;
2264
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002265 case HCI_OP_DELETE_STORED_LINK_KEY:
2266 hci_cc_delete_stored_link_key(hdev, skb);
2267 break;
2268
Johan Hedbergd5859e22011-01-25 01:19:58 +02002269 case HCI_OP_SET_EVENT_MASK:
2270 hci_cc_set_event_mask(hdev, skb);
2271 break;
2272
2273 case HCI_OP_WRITE_INQUIRY_MODE:
2274 hci_cc_write_inquiry_mode(hdev, skb);
2275 break;
2276
2277 case HCI_OP_READ_INQ_RSP_TX_POWER:
2278 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2279 break;
2280
2281 case HCI_OP_SET_EVENT_FLT:
2282 hci_cc_set_event_flt(hdev, skb);
2283 break;
2284
Johan Hedberg980e1a52011-01-22 06:10:07 +02002285 case HCI_OP_PIN_CODE_REPLY:
2286 hci_cc_pin_code_reply(hdev, skb);
2287 break;
2288
2289 case HCI_OP_PIN_CODE_NEG_REPLY:
2290 hci_cc_pin_code_neg_reply(hdev, skb);
2291 break;
2292
Szymon Jancc35938b2011-03-22 13:12:21 +01002293 case HCI_OP_READ_LOCAL_OOB_DATA:
2294 hci_cc_read_local_oob_data_reply(hdev, skb);
2295 break;
2296
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002297 case HCI_OP_LE_READ_BUFFER_SIZE:
2298 hci_cc_le_read_buffer_size(hdev, skb);
2299 break;
2300
Johan Hedberga5c29682011-02-19 12:05:57 -03002301 case HCI_OP_USER_CONFIRM_REPLY:
2302 hci_cc_user_confirm_reply(hdev, skb);
2303 break;
2304
2305 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2306 hci_cc_user_confirm_neg_reply(hdev, skb);
2307 break;
2308
Brian Gix1143d452011-11-23 08:28:34 -08002309 case HCI_OP_USER_PASSKEY_REPLY:
2310 hci_cc_user_passkey_reply(hdev, skb);
2311 break;
2312
2313 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2314 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002315
2316 case HCI_OP_LE_SET_SCAN_PARAM:
2317 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002318 break;
2319
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002320 case HCI_OP_LE_SET_SCAN_ENABLE:
2321 hci_cc_le_set_scan_enable(hdev, skb);
2322 break;
2323
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002324 case HCI_OP_LE_LTK_REPLY:
2325 hci_cc_le_ltk_reply(hdev, skb);
2326 break;
2327
2328 case HCI_OP_LE_LTK_NEG_REPLY:
2329 hci_cc_le_ltk_neg_reply(hdev, skb);
2330 break;
2331
Andre Guedesf9b49302011-06-30 19:20:53 -03002332 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2333 hci_cc_write_le_host_supported(hdev, skb);
2334 break;
2335
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002336 default:
2337 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2338 break;
2339 }
2340
Ville Tervo6bd32322011-02-16 16:32:41 +02002341 if (ev->opcode != HCI_OP_NOP)
2342 del_timer(&hdev->cmd_timer);
2343
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002344 if (ev->ncmd) {
2345 atomic_set(&hdev->cmd_cnt, 1);
2346 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002347 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002348 }
2349}
2350
2351static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2352{
2353 struct hci_ev_cmd_status *ev = (void *) skb->data;
2354 __u16 opcode;
2355
2356 skb_pull(skb, sizeof(*ev));
2357
2358 opcode = __le16_to_cpu(ev->opcode);
2359
2360 switch (opcode) {
2361 case HCI_OP_INQUIRY:
2362 hci_cs_inquiry(hdev, ev->status);
2363 break;
2364
2365 case HCI_OP_CREATE_CONN:
2366 hci_cs_create_conn(hdev, ev->status);
2367 break;
2368
2369 case HCI_OP_ADD_SCO:
2370 hci_cs_add_sco(hdev, ev->status);
2371 break;
2372
Marcel Holtmannf8558552008-07-14 20:13:49 +02002373 case HCI_OP_AUTH_REQUESTED:
2374 hci_cs_auth_requested(hdev, ev->status);
2375 break;
2376
2377 case HCI_OP_SET_CONN_ENCRYPT:
2378 hci_cs_set_conn_encrypt(hdev, ev->status);
2379 break;
2380
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002381 case HCI_OP_REMOTE_NAME_REQ:
2382 hci_cs_remote_name_req(hdev, ev->status);
2383 break;
2384
Marcel Holtmann769be972008-07-14 20:13:49 +02002385 case HCI_OP_READ_REMOTE_FEATURES:
2386 hci_cs_read_remote_features(hdev, ev->status);
2387 break;
2388
2389 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2390 hci_cs_read_remote_ext_features(hdev, ev->status);
2391 break;
2392
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002393 case HCI_OP_SETUP_SYNC_CONN:
2394 hci_cs_setup_sync_conn(hdev, ev->status);
2395 break;
2396
2397 case HCI_OP_SNIFF_MODE:
2398 hci_cs_sniff_mode(hdev, ev->status);
2399 break;
2400
2401 case HCI_OP_EXIT_SNIFF_MODE:
2402 hci_cs_exit_sniff_mode(hdev, ev->status);
2403 break;
2404
Johan Hedberg8962ee72011-01-20 12:40:27 +02002405 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002406 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002407 break;
2408
Ville Tervofcd89c02011-02-10 22:38:47 -03002409 case HCI_OP_LE_CREATE_CONN:
2410 hci_cs_le_create_conn(hdev, ev->status);
2411 break;
2412
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002413 case HCI_OP_LE_START_ENC:
2414 hci_cs_le_start_enc(hdev, ev->status);
2415 break;
2416
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002417 default:
2418 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2419 break;
2420 }
2421
Ville Tervo6bd32322011-02-16 16:32:41 +02002422 if (ev->opcode != HCI_OP_NOP)
2423 del_timer(&hdev->cmd_timer);
2424
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002425 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002426 atomic_set(&hdev->cmd_cnt, 1);
2427 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002428 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002429 }
2430}
2431
2432static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2433{
2434 struct hci_ev_role_change *ev = (void *) skb->data;
2435 struct hci_conn *conn;
2436
2437 BT_DBG("%s status %d", hdev->name, ev->status);
2438
2439 hci_dev_lock(hdev);
2440
2441 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2442 if (conn) {
2443 if (!ev->status) {
2444 if (ev->role)
2445 conn->link_mode &= ~HCI_LM_MASTER;
2446 else
2447 conn->link_mode |= HCI_LM_MASTER;
2448 }
2449
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002450 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002451
2452 hci_role_switch_cfm(conn, ev->status, ev->role);
2453 }
2454
2455 hci_dev_unlock(hdev);
2456}
2457
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2459{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002460 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002461 int i;
2462
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002463 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2464 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2465 return;
2466 }
2467
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002468 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2469 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002470 BT_DBG("%s bad parameters", hdev->name);
2471 return;
2472 }
2473
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002474 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2475
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002476 for (i = 0; i < ev->num_hndl; i++) {
2477 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002478 struct hci_conn *conn;
2479 __u16 handle, count;
2480
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002481 handle = __le16_to_cpu(info->handle);
2482 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483
2484 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002485 if (!conn)
2486 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002488 conn->sent -= count;
2489
2490 switch (conn->type) {
2491 case ACL_LINK:
2492 hdev->acl_cnt += count;
2493 if (hdev->acl_cnt > hdev->acl_pkts)
2494 hdev->acl_cnt = hdev->acl_pkts;
2495 break;
2496
2497 case LE_LINK:
2498 if (hdev->le_pkts) {
2499 hdev->le_cnt += count;
2500 if (hdev->le_cnt > hdev->le_pkts)
2501 hdev->le_cnt = hdev->le_pkts;
2502 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002503 hdev->acl_cnt += count;
2504 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505 hdev->acl_cnt = hdev->acl_pkts;
2506 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002507 break;
2508
2509 case SCO_LINK:
2510 hdev->sco_cnt += count;
2511 if (hdev->sco_cnt > hdev->sco_pkts)
2512 hdev->sco_cnt = hdev->sco_pkts;
2513 break;
2514
2515 default:
2516 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2517 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002518 }
2519 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002520
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002521 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522}
2523
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002524static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2525 struct sk_buff *skb)
2526{
2527 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2528 int i;
2529
2530 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2531 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2532 return;
2533 }
2534
2535 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2536 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2537 BT_DBG("%s bad parameters", hdev->name);
2538 return;
2539 }
2540
2541 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2542 ev->num_hndl);
2543
2544 for (i = 0; i < ev->num_hndl; i++) {
2545 struct hci_comp_blocks_info *info = &ev->handles[i];
2546 struct hci_conn *conn;
2547 __u16 handle, block_count;
2548
2549 handle = __le16_to_cpu(info->handle);
2550 block_count = __le16_to_cpu(info->blocks);
2551
2552 conn = hci_conn_hash_lookup_handle(hdev, handle);
2553 if (!conn)
2554 continue;
2555
2556 conn->sent -= block_count;
2557
2558 switch (conn->type) {
2559 case ACL_LINK:
2560 hdev->block_cnt += block_count;
2561 if (hdev->block_cnt > hdev->num_blocks)
2562 hdev->block_cnt = hdev->num_blocks;
2563 break;
2564
2565 default:
2566 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2567 break;
2568 }
2569 }
2570
2571 queue_work(hdev->workqueue, &hdev->tx_work);
2572}
2573
Marcel Holtmann04837f62006-07-03 10:02:33 +02002574static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002576 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002577 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578
2579 BT_DBG("%s status %d", hdev->name, ev->status);
2580
2581 hci_dev_lock(hdev);
2582
Marcel Holtmann04837f62006-07-03 10:02:33 +02002583 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2584 if (conn) {
2585 conn->mode = ev->mode;
2586 conn->interval = __le16_to_cpu(ev->interval);
2587
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002588 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002589 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002590 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002591 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002592 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002593 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002594
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002595 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002596 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002597 }
2598
2599 hci_dev_unlock(hdev);
2600}
2601
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2603{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002604 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2605 struct hci_conn *conn;
2606
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002607 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002608
2609 hci_dev_lock(hdev);
2610
2611 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002612 if (!conn)
2613 goto unlock;
2614
2615 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002616 hci_conn_hold(conn);
2617 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2618 hci_conn_put(conn);
2619 }
2620
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002621 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002622 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2623 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002624 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002625 u8 secure;
2626
2627 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2628 secure = 1;
2629 else
2630 secure = 0;
2631
Johan Hedberg744cf192011-11-08 20:40:14 +02002632 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002633 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002634
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002635unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002636 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637}
2638
Linus Torvalds1da177e2005-04-16 15:20:36 -07002639static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2640{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002641 struct hci_ev_link_key_req *ev = (void *) skb->data;
2642 struct hci_cp_link_key_reply cp;
2643 struct hci_conn *conn;
2644 struct link_key *key;
2645
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002646 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002647
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002648 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002649 return;
2650
2651 hci_dev_lock(hdev);
2652
2653 key = hci_find_link_key(hdev, &ev->bdaddr);
2654 if (!key) {
2655 BT_DBG("%s link key not found for %s", hdev->name,
2656 batostr(&ev->bdaddr));
2657 goto not_found;
2658 }
2659
2660 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2661 batostr(&ev->bdaddr));
2662
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002663 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002664 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002665 BT_DBG("%s ignoring debug key", hdev->name);
2666 goto not_found;
2667 }
2668
2669 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002670 if (conn) {
2671 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2672 conn->auth_type != 0xff &&
2673 (conn->auth_type & 0x01)) {
2674 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2675 goto not_found;
2676 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002677
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002678 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2679 conn->pending_sec_level == BT_SECURITY_HIGH) {
2680 BT_DBG("%s ignoring key unauthenticated for high \
2681 security", hdev->name);
2682 goto not_found;
2683 }
2684
2685 conn->key_type = key->type;
2686 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002687 }
2688
2689 bacpy(&cp.bdaddr, &ev->bdaddr);
2690 memcpy(cp.link_key, key->val, 16);
2691
2692 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2693
2694 hci_dev_unlock(hdev);
2695
2696 return;
2697
2698not_found:
2699 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2700 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002701}
2702
Linus Torvalds1da177e2005-04-16 15:20:36 -07002703static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2704{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002705 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2706 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002707 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002708
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002709 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002710
2711 hci_dev_lock(hdev);
2712
2713 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2714 if (conn) {
2715 hci_conn_hold(conn);
2716 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002717 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002718
2719 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2720 conn->key_type = ev->key_type;
2721
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002722 hci_conn_put(conn);
2723 }
2724
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002725 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002726 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002727 ev->key_type, pin_len);
2728
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002729 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730}
2731
Marcel Holtmann04837f62006-07-03 10:02:33 +02002732static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2733{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002734 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002735 struct hci_conn *conn;
2736
2737 BT_DBG("%s status %d", hdev->name, ev->status);
2738
2739 hci_dev_lock(hdev);
2740
2741 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742 if (conn && !ev->status) {
2743 struct inquiry_entry *ie;
2744
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002745 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2746 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002747 ie->data.clock_offset = ev->clock_offset;
2748 ie->timestamp = jiffies;
2749 }
2750 }
2751
2752 hci_dev_unlock(hdev);
2753}
2754
Marcel Holtmanna8746412008-07-14 20:13:46 +02002755static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2756{
2757 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2758 struct hci_conn *conn;
2759
2760 BT_DBG("%s status %d", hdev->name, ev->status);
2761
2762 hci_dev_lock(hdev);
2763
2764 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2765 if (conn && !ev->status)
2766 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2767
2768 hci_dev_unlock(hdev);
2769}
2770
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002771static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2772{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002773 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002774 struct inquiry_entry *ie;
2775
2776 BT_DBG("%s", hdev->name);
2777
2778 hci_dev_lock(hdev);
2779
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002780 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2781 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002782 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2783 ie->timestamp = jiffies;
2784 }
2785
2786 hci_dev_unlock(hdev);
2787}
2788
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002789static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2790{
2791 struct inquiry_data data;
2792 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002793 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002794
2795 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2796
2797 if (!num_rsp)
2798 return;
2799
2800 hci_dev_lock(hdev);
2801
2802 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002803 struct inquiry_info_with_rssi_and_pscan_mode *info;
2804 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002805
Johan Hedberge17acd42011-03-30 23:57:16 +03002806 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002807 bacpy(&data.bdaddr, &info->bdaddr);
2808 data.pscan_rep_mode = info->pscan_rep_mode;
2809 data.pscan_period_mode = info->pscan_period_mode;
2810 data.pscan_mode = info->pscan_mode;
2811 memcpy(data.dev_class, info->dev_class, 3);
2812 data.clock_offset = info->clock_offset;
2813 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002814 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002815
2816 name_known = hci_inquiry_cache_update(hdev, &data,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002817 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002818 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002819 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002820 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002821 }
2822 } else {
2823 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2824
Johan Hedberge17acd42011-03-30 23:57:16 +03002825 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002826 bacpy(&data.bdaddr, &info->bdaddr);
2827 data.pscan_rep_mode = info->pscan_rep_mode;
2828 data.pscan_period_mode = info->pscan_period_mode;
2829 data.pscan_mode = 0x00;
2830 memcpy(data.dev_class, info->dev_class, 3);
2831 data.clock_offset = info->clock_offset;
2832 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002833 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002834 name_known = hci_inquiry_cache_update(hdev, &data,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002835 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002836 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002837 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002838 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002839 }
2840 }
2841
2842 hci_dev_unlock(hdev);
2843}
2844
2845static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2846{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002847 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2848 struct hci_conn *conn;
2849
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002850 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002851
Marcel Holtmann41a96212008-07-14 20:13:48 +02002852 hci_dev_lock(hdev);
2853
2854 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002855 if (!conn)
2856 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002857
Johan Hedbergccd556f2010-11-10 17:11:51 +02002858 if (!ev->status && ev->page == 0x01) {
2859 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002860
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002861 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2862 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002863 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002864
Johan Hedberg58a681e2012-01-16 06:47:28 +02002865 if (ev->features[0] & 0x01)
2866 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002867 }
2868
Johan Hedbergccd556f2010-11-10 17:11:51 +02002869 if (conn->state != BT_CONFIG)
2870 goto unlock;
2871
Johan Hedberg127178d2010-11-18 22:22:29 +02002872 if (!ev->status) {
2873 struct hci_cp_remote_name_req cp;
2874 memset(&cp, 0, sizeof(cp));
2875 bacpy(&cp.bdaddr, &conn->dst);
2876 cp.pscan_rep_mode = 0x02;
2877 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002878 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2879 mgmt_device_connected(hdev, &conn->dst, conn->type,
Johan Hedberg08c79b62012-02-23 22:31:51 +02002880 conn->dst_type, 0, NULL, 0,
Johan Hedbergb644ba32012-01-17 21:48:47 +02002881 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002882
Johan Hedberg127178d2010-11-18 22:22:29 +02002883 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002884 conn->state = BT_CONNECTED;
2885 hci_proto_connect_cfm(conn, ev->status);
2886 hci_conn_put(conn);
2887 }
2888
2889unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002890 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002891}
2892
2893static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2894{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002895 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2896 struct hci_conn *conn;
2897
2898 BT_DBG("%s status %d", hdev->name, ev->status);
2899
2900 hci_dev_lock(hdev);
2901
2902 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002903 if (!conn) {
2904 if (ev->link_type == ESCO_LINK)
2905 goto unlock;
2906
2907 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2908 if (!conn)
2909 goto unlock;
2910
2911 conn->type = SCO_LINK;
2912 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002913
Marcel Holtmann732547f2009-04-19 19:14:14 +02002914 switch (ev->status) {
2915 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002916 conn->handle = __le16_to_cpu(ev->handle);
2917 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002918
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002919 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002920 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002921 break;
2922
Stephen Coe705e5712010-02-16 11:29:44 -05002923 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002924 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002925 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002926 case 0x1f: /* Unspecified error */
2927 if (conn->out && conn->attempt < 2) {
2928 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2929 (hdev->esco_type & EDR_ESCO_MASK);
2930 hci_setup_sync(conn, conn->link->handle);
2931 goto unlock;
2932 }
2933 /* fall through */
2934
2935 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002936 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002937 break;
2938 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002939
2940 hci_proto_connect_cfm(conn, ev->status);
2941 if (ev->status)
2942 hci_conn_del(conn);
2943
2944unlock:
2945 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002946}
2947
2948static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2949{
2950 BT_DBG("%s", hdev->name);
2951}
2952
Marcel Holtmann04837f62006-07-03 10:02:33 +02002953static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2954{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002955 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002956
2957 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002958}
2959
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002960static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2961{
2962 struct inquiry_data data;
2963 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2964 int num_rsp = *((__u8 *) skb->data);
2965
2966 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2967
2968 if (!num_rsp)
2969 return;
2970
2971 hci_dev_lock(hdev);
2972
Johan Hedberge17acd42011-03-30 23:57:16 +03002973 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002974 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002975
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002976 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002977 data.pscan_rep_mode = info->pscan_rep_mode;
2978 data.pscan_period_mode = info->pscan_period_mode;
2979 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002980 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002981 data.clock_offset = info->clock_offset;
2982 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002983 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002984
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002985 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002986 name_known = eir_has_data_type(info->data,
2987 sizeof(info->data),
2988 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002989 else
2990 name_known = true;
2991
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002992 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
2993 &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002994 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002995 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002996 !name_known, ssp, info->data,
Andre Guedes7d262f82012-01-10 18:20:49 -03002997 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002998 }
2999
3000 hci_dev_unlock(hdev);
3001}
3002
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003003static inline u8 hci_get_auth_req(struct hci_conn *conn)
3004{
3005 /* If remote requests dedicated bonding follow that lead */
3006 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3007 /* If both remote and local IO capabilities allow MITM
3008 * protection then require it, otherwise don't */
3009 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3010 return 0x02;
3011 else
3012 return 0x03;
3013 }
3014
3015 /* If remote requests no-bonding follow that lead */
3016 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003017 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003018
3019 return conn->auth_type;
3020}
3021
Marcel Holtmann04936842008-07-14 20:13:48 +02003022static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3023{
3024 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3025 struct hci_conn *conn;
3026
3027 BT_DBG("%s", hdev->name);
3028
3029 hci_dev_lock(hdev);
3030
3031 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003032 if (!conn)
3033 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003034
Johan Hedberg03b555e2011-01-04 15:40:05 +02003035 hci_conn_hold(conn);
3036
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003037 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003038 goto unlock;
3039
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003040 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003041 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003042 struct hci_cp_io_capability_reply cp;
3043
3044 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303045 /* Change the IO capability from KeyboardDisplay
3046 * to DisplayYesNo as it is not supported by BT spec. */
3047 cp.capability = (conn->io_capability == 0x04) ?
3048 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003049 conn->auth_type = hci_get_auth_req(conn);
3050 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003051
Johan Hedberg58a681e2012-01-16 06:47:28 +02003052 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003053 hci_find_remote_oob_data(hdev, &conn->dst))
3054 cp.oob_data = 0x01;
3055 else
3056 cp.oob_data = 0x00;
3057
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003058 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3059 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003060 } else {
3061 struct hci_cp_io_capability_neg_reply cp;
3062
3063 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003064 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003065
3066 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3067 sizeof(cp), &cp);
3068 }
3069
3070unlock:
3071 hci_dev_unlock(hdev);
3072}
3073
3074static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3075{
3076 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3077 struct hci_conn *conn;
3078
3079 BT_DBG("%s", hdev->name);
3080
3081 hci_dev_lock(hdev);
3082
3083 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3084 if (!conn)
3085 goto unlock;
3086
Johan Hedberg03b555e2011-01-04 15:40:05 +02003087 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003088 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003089 if (ev->oob_data)
3090 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003091
3092unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003093 hci_dev_unlock(hdev);
3094}
3095
Johan Hedberga5c29682011-02-19 12:05:57 -03003096static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3097 struct sk_buff *skb)
3098{
3099 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003100 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003101 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003102
3103 BT_DBG("%s", hdev->name);
3104
3105 hci_dev_lock(hdev);
3106
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003107 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003108 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003109
Johan Hedberg7a828902011-04-28 11:28:53 -07003110 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3111 if (!conn)
3112 goto unlock;
3113
3114 loc_mitm = (conn->auth_type & 0x01);
3115 rem_mitm = (conn->remote_auth & 0x01);
3116
3117 /* If we require MITM but the remote device can't provide that
3118 * (it has NoInputNoOutput) then reject the confirmation
3119 * request. The only exception is when we're dedicated bonding
3120 * initiators (connect_cfm_cb set) since then we always have the MITM
3121 * bit set. */
3122 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3123 BT_DBG("Rejecting request: remote device can't provide MITM");
3124 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3125 sizeof(ev->bdaddr), &ev->bdaddr);
3126 goto unlock;
3127 }
3128
3129 /* If no side requires MITM protection; auto-accept */
3130 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3131 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003132
3133 /* If we're not the initiators request authorization to
3134 * proceed from user space (mgmt_user_confirm with
3135 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003136 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003137 BT_DBG("Confirming auto-accept as acceptor");
3138 confirm_hint = 1;
3139 goto confirm;
3140 }
3141
Johan Hedberg9f616562011-04-28 11:28:54 -07003142 BT_DBG("Auto-accept of user confirmation with %ums delay",
3143 hdev->auto_accept_delay);
3144
3145 if (hdev->auto_accept_delay > 0) {
3146 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3147 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3148 goto unlock;
3149 }
3150
Johan Hedberg7a828902011-04-28 11:28:53 -07003151 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3152 sizeof(ev->bdaddr), &ev->bdaddr);
3153 goto unlock;
3154 }
3155
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003156confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003157 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003158 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003159
3160unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003161 hci_dev_unlock(hdev);
3162}
3163
Brian Gix1143d452011-11-23 08:28:34 -08003164static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3165 struct sk_buff *skb)
3166{
3167 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3168
3169 BT_DBG("%s", hdev->name);
3170
3171 hci_dev_lock(hdev);
3172
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003173 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003174 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003175
3176 hci_dev_unlock(hdev);
3177}
3178
Marcel Holtmann04936842008-07-14 20:13:48 +02003179static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3180{
3181 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3182 struct hci_conn *conn;
3183
3184 BT_DBG("%s", hdev->name);
3185
3186 hci_dev_lock(hdev);
3187
3188 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003189 if (!conn)
3190 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003191
Johan Hedberg2a611692011-02-19 12:06:00 -03003192 /* To avoid duplicate auth_failed events to user space we check
3193 * the HCI_CONN_AUTH_PEND flag which will be set if we
3194 * initiated the authentication. A traditional auth_complete
3195 * event gets always produced as initiator and is also mapped to
3196 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003197 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003198 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3199 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003200
3201 hci_conn_put(conn);
3202
3203unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003204 hci_dev_unlock(hdev);
3205}
3206
Marcel Holtmann41a96212008-07-14 20:13:48 +02003207static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3208{
3209 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3210 struct inquiry_entry *ie;
3211
3212 BT_DBG("%s", hdev->name);
3213
3214 hci_dev_lock(hdev);
3215
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003216 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3217 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003218 ie->data.ssp_mode = (ev->features[0] & 0x01);
3219
3220 hci_dev_unlock(hdev);
3221}
3222
Szymon Janc2763eda2011-03-22 13:12:22 +01003223static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3224 struct sk_buff *skb)
3225{
3226 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3227 struct oob_data *data;
3228
3229 BT_DBG("%s", hdev->name);
3230
3231 hci_dev_lock(hdev);
3232
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003233 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003234 goto unlock;
3235
Szymon Janc2763eda2011-03-22 13:12:22 +01003236 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3237 if (data) {
3238 struct hci_cp_remote_oob_data_reply cp;
3239
3240 bacpy(&cp.bdaddr, &ev->bdaddr);
3241 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3242 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3243
3244 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3245 &cp);
3246 } else {
3247 struct hci_cp_remote_oob_data_neg_reply cp;
3248
3249 bacpy(&cp.bdaddr, &ev->bdaddr);
3250 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3251 &cp);
3252 }
3253
Szymon Jance1ba1f12011-04-06 13:01:59 +02003254unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003255 hci_dev_unlock(hdev);
3256}
3257
Ville Tervofcd89c02011-02-10 22:38:47 -03003258static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3259{
3260 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3261 struct hci_conn *conn;
3262
3263 BT_DBG("%s status %d", hdev->name, ev->status);
3264
3265 hci_dev_lock(hdev);
3266
3267 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003268 if (!conn) {
3269 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3270 if (!conn) {
3271 BT_ERR("No memory for new connection");
3272 hci_dev_unlock(hdev);
3273 return;
3274 }
Andre Guedes29b79882011-05-31 14:20:54 -03003275
3276 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003277 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003278
3279 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003280 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3281 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003282 hci_proto_connect_cfm(conn, ev->status);
3283 conn->state = BT_CLOSED;
3284 hci_conn_del(conn);
3285 goto unlock;
3286 }
3287
Johan Hedbergb644ba32012-01-17 21:48:47 +02003288 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3289 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Johan Hedberg08c79b62012-02-23 22:31:51 +02003290 conn->dst_type, 0, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003291
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003292 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003293 conn->handle = __le16_to_cpu(ev->handle);
3294 conn->state = BT_CONNECTED;
3295
3296 hci_conn_hold_device(conn);
3297 hci_conn_add_sysfs(conn);
3298
3299 hci_proto_connect_cfm(conn, ev->status);
3300
3301unlock:
3302 hci_dev_unlock(hdev);
3303}
3304
Andre Guedes9aa04c92011-05-26 16:23:51 -03003305static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3306 struct sk_buff *skb)
3307{
Andre Guedese95beb42011-09-26 20:48:35 -03003308 u8 num_reports = skb->data[0];
3309 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003310 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003311
3312 hci_dev_lock(hdev);
3313
Andre Guedese95beb42011-09-26 20:48:35 -03003314 while (num_reports--) {
3315 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003316
Andre Guedes9aa04c92011-05-26 16:23:51 -03003317 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003318
Andre Guedes3c9e9192012-01-10 18:20:50 -03003319 rssi = ev->data[ev->length];
3320 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003321 NULL, rssi, 0, 1, ev->data,
3322 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}