blob: 8c3261db7611863d94554c624f6bfef8a27a6a7c [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <net/sock.h>
39
40#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020041#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <asm/unaligned.h>
43
44#include <net/bluetooth/bluetooth.h>
45#include <net/bluetooth/hci_core.h>
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047/* Handle HCI Event packets */
48
Marcel Holtmanna9de9242007-10-20 13:33:56 +020049static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070050{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020051 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
Marcel Holtmanna9de9242007-10-20 13:33:56 +020053 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Andre Guedese6d465c2011-11-09 17:14:26 -030055 if (status) {
56 hci_dev_lock(hdev);
57 mgmt_stop_discovery_failed(hdev, status);
58 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020059 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030060 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
Andre Guedes89352e72011-11-04 14:16:53 -030062 clear_bit(HCI_INQUIRY, &hdev->flags);
63
Johan Hedberg56e5cb82011-11-08 20:40:16 +020064 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020065 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020066 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010067
Johan Hedberg23bb5762010-12-21 23:01:27 +020068 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010069
Marcel Holtmanna9de9242007-10-20 13:33:56 +020070 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070071}
72
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020075 __u8 status = *((__u8 *) skb->data);
76
77 BT_DBG("%s status 0x%x", hdev->name, status);
78
79 if (status)
80 return;
81
Marcel Holtmanna9de9242007-10-20 13:33:56 +020082 hci_conn_check_pending(hdev);
83}
84
85static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
86{
87 BT_DBG("%s", hdev->name);
88}
89
90static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
91{
92 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 if (rp->status)
98 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200102 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
103 if (conn) {
104 if (rp->role)
105 conn->link_mode &= ~HCI_LM_MASTER;
106 else
107 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200109
110 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111}
112
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200113static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
114{
115 struct hci_rp_read_link_policy *rp = (void *) skb->data;
116 struct hci_conn *conn;
117
118 BT_DBG("%s status 0x%x", hdev->name, rp->status);
119
120 if (rp->status)
121 return;
122
123 hci_dev_lock(hdev);
124
125 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
126 if (conn)
127 conn->link_policy = __le16_to_cpu(rp->policy);
128
129 hci_dev_unlock(hdev);
130}
131
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200132static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200134 struct hci_rp_write_link_policy *rp = (void *) skb->data;
135 struct hci_conn *conn;
136 void *sent;
137
138 BT_DBG("%s status 0x%x", hdev->name, rp->status);
139
140 if (rp->status)
141 return;
142
143 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
144 if (!sent)
145 return;
146
147 hci_dev_lock(hdev);
148
149 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200150 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700151 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200152
153 hci_dev_unlock(hdev);
154}
155
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200156static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
157{
158 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
159
160 BT_DBG("%s status 0x%x", hdev->name, rp->status);
161
162 if (rp->status)
163 return;
164
165 hdev->link_policy = __le16_to_cpu(rp->policy);
166}
167
168static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
169{
170 __u8 status = *((__u8 *) skb->data);
171 void *sent;
172
173 BT_DBG("%s status 0x%x", hdev->name, status);
174
175 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
176 if (!sent)
177 return;
178
179 if (!status)
180 hdev->link_policy = get_unaligned_le16(sent);
181
Johan Hedberg23bb5762010-12-21 23:01:27 +0200182 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200183}
184
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200185static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
186{
187 __u8 status = *((__u8 *) skb->data);
188
189 BT_DBG("%s status 0x%x", hdev->name, status);
190
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300191 clear_bit(HCI_RESET, &hdev->flags);
192
Johan Hedberg23bb5762010-12-21 23:01:27 +0200193 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300194
Johan Hedberga297e972012-02-21 17:55:47 +0200195 /* Reset all non-persistent flags */
196 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN));
Andre Guedes69775ff2012-02-23 16:50:05 +0200197
198 hdev->discovery.state = DISCOVERY_STOPPED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200199}
200
201static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
202{
203 __u8 status = *((__u8 *) skb->data);
204 void *sent;
205
206 BT_DBG("%s status 0x%x", hdev->name, status);
207
208 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
209 if (!sent)
210 return;
211
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200212 hci_dev_lock(hdev);
213
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200214 if (test_bit(HCI_MGMT, &hdev->dev_flags))
215 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200216 else if (!status)
217 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200218
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200219 hci_dev_unlock(hdev);
Johan Hedberg3159d382012-02-24 13:47:56 +0200220
221 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200222}
223
224static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
225{
226 struct hci_rp_read_local_name *rp = (void *) skb->data;
227
228 BT_DBG("%s status 0x%x", hdev->name, rp->status);
229
230 if (rp->status)
231 return;
232
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200233 if (test_bit(HCI_SETUP, &hdev->dev_flags))
234 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200235}
236
237static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
238{
239 __u8 status = *((__u8 *) skb->data);
240 void *sent;
241
242 BT_DBG("%s status 0x%x", hdev->name, status);
243
244 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
245 if (!sent)
246 return;
247
248 if (!status) {
249 __u8 param = *((__u8 *) sent);
250
251 if (param == AUTH_ENABLED)
252 set_bit(HCI_AUTH, &hdev->flags);
253 else
254 clear_bit(HCI_AUTH, &hdev->flags);
255 }
256
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200257 if (test_bit(HCI_MGMT, &hdev->dev_flags))
258 mgmt_auth_enable_complete(hdev, status);
259
Johan Hedberg23bb5762010-12-21 23:01:27 +0200260 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200261}
262
263static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
264{
265 __u8 status = *((__u8 *) skb->data);
266 void *sent;
267
268 BT_DBG("%s status 0x%x", hdev->name, status);
269
270 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
271 if (!sent)
272 return;
273
274 if (!status) {
275 __u8 param = *((__u8 *) sent);
276
277 if (param)
278 set_bit(HCI_ENCRYPT, &hdev->flags);
279 else
280 clear_bit(HCI_ENCRYPT, &hdev->flags);
281 }
282
Johan Hedberg23bb5762010-12-21 23:01:27 +0200283 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200284}
285
286static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
287{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200288 __u8 param, status = *((__u8 *) skb->data);
289 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200290 void *sent;
291
292 BT_DBG("%s status 0x%x", hdev->name, status);
293
294 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
295 if (!sent)
296 return;
297
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200298 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200299
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200300 hci_dev_lock(hdev);
301
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200302 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200303 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200304 hdev->discov_timeout = 0;
305 goto done;
306 }
307
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200308 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
309 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200310
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200311 if (param & SCAN_INQUIRY) {
312 set_bit(HCI_ISCAN, &hdev->flags);
313 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200314 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200315 if (hdev->discov_timeout > 0) {
316 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
317 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
318 to);
319 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200320 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200321 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200322
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 if (param & SCAN_PAGE) {
324 set_bit(HCI_PSCAN, &hdev->flags);
325 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200328 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200329
330done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200331 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200332 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200333}
334
335static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
336{
337 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
338
339 BT_DBG("%s status 0x%x", hdev->name, rp->status);
340
341 if (rp->status)
342 return;
343
344 memcpy(hdev->dev_class, rp->dev_class, 3);
345
346 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
347 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
348}
349
350static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
351{
352 __u8 status = *((__u8 *) skb->data);
353 void *sent;
354
355 BT_DBG("%s status 0x%x", hdev->name, status);
356
357 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
358 if (!sent)
359 return;
360
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100361 hci_dev_lock(hdev);
362
363 if (status == 0)
364 memcpy(hdev->dev_class, sent, 3);
365
366 if (test_bit(HCI_MGMT, &hdev->dev_flags))
367 mgmt_set_class_of_dev_complete(hdev, sent, status);
368
369 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200370}
371
372static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
373{
374 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200376
377 BT_DBG("%s status 0x%x", hdev->name, rp->status);
378
379 if (rp->status)
380 return;
381
382 setting = __le16_to_cpu(rp->voice_setting);
383
Marcel Holtmannf383f272008-07-14 20:13:47 +0200384 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200385 return;
386
387 hdev->voice_setting = setting;
388
389 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
390
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200391 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200393}
394
395static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
396{
397 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200398 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 void *sent;
400
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200401 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Marcel Holtmannf383f272008-07-14 20:13:47 +0200403 if (status)
404 return;
405
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200406 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
407 if (!sent)
408 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Marcel Holtmannf383f272008-07-14 20:13:47 +0200412 if (hdev->voice_setting == setting)
413 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Marcel Holtmannf383f272008-07-14 20:13:47 +0200415 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Marcel Holtmannf383f272008-07-14 20:13:47 +0200417 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
418
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200419 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200420 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421}
422
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200423static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200425 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200427 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428
Johan Hedberg23bb5762010-12-21 23:01:27 +0200429 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430}
431
Marcel Holtmann333140b2008-07-14 20:13:48 +0200432static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
433{
434 __u8 status = *((__u8 *) skb->data);
435 void *sent;
436
437 BT_DBG("%s status 0x%x", hdev->name, status);
438
Marcel Holtmann333140b2008-07-14 20:13:48 +0200439 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
440 if (!sent)
441 return;
442
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200443 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200444 mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status);
445 else if (!status) {
446 if (*((u8 *) sent))
447 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
448 else
449 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
450 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200451}
452
Johan Hedbergd5859e22011-01-25 01:19:58 +0200453static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
454{
455 if (hdev->features[6] & LMP_EXT_INQ)
456 return 2;
457
458 if (hdev->features[3] & LMP_RSSI_INQ)
459 return 1;
460
461 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
462 hdev->lmp_subver == 0x0757)
463 return 1;
464
465 if (hdev->manufacturer == 15) {
466 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
467 return 1;
468 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
469 return 1;
470 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
471 return 1;
472 }
473
474 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
475 hdev->lmp_subver == 0x1805)
476 return 1;
477
478 return 0;
479}
480
481static void hci_setup_inquiry_mode(struct hci_dev *hdev)
482{
483 u8 mode;
484
485 mode = hci_get_inquiry_mode(hdev);
486
487 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
488}
489
490static void hci_setup_event_mask(struct hci_dev *hdev)
491{
492 /* The second byte is 0xff instead of 0x9f (two reserved bits
493 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
494 * command otherwise */
495 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
496
Ville Tervo6de6c182011-05-27 11:16:21 +0300497 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
498 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200499 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300500 return;
501
502 events[4] |= 0x01; /* Flow Specification Complete */
503 events[4] |= 0x02; /* Inquiry Result with RSSI */
504 events[4] |= 0x04; /* Read Remote Extended Features Complete */
505 events[5] |= 0x08; /* Synchronous Connection Complete */
506 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200507
508 if (hdev->features[3] & LMP_RSSI_INQ)
509 events[4] |= 0x04; /* Inquiry Result with RSSI */
510
511 if (hdev->features[5] & LMP_SNIFF_SUBR)
512 events[5] |= 0x20; /* Sniff Subrating */
513
514 if (hdev->features[5] & LMP_PAUSE_ENC)
515 events[5] |= 0x80; /* Encryption Key Refresh Complete */
516
517 if (hdev->features[6] & LMP_EXT_INQ)
518 events[5] |= 0x40; /* Extended Inquiry Result */
519
520 if (hdev->features[6] & LMP_NO_FLUSH)
521 events[7] |= 0x01; /* Enhanced Flush Complete */
522
523 if (hdev->features[7] & LMP_LSTO)
524 events[6] |= 0x80; /* Link Supervision Timeout Changed */
525
526 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
527 events[6] |= 0x01; /* IO Capability Request */
528 events[6] |= 0x02; /* IO Capability Response */
529 events[6] |= 0x04; /* User Confirmation Request */
530 events[6] |= 0x08; /* User Passkey Request */
531 events[6] |= 0x10; /* Remote OOB Data Request */
532 events[6] |= 0x20; /* Simple Pairing Complete */
533 events[7] |= 0x04; /* User Passkey Notification */
534 events[7] |= 0x08; /* Keypress Notification */
535 events[7] |= 0x10; /* Remote Host Supported
536 * Features Notification */
537 }
538
539 if (hdev->features[4] & LMP_LE)
540 events[7] |= 0x20; /* LE Meta-Event */
541
542 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
543}
544
545static void hci_setup(struct hci_dev *hdev)
546{
Andrei Emeltchenkoe61ef492011-12-19 16:31:27 +0200547 if (hdev->dev_type != HCI_BREDR)
548 return;
549
Johan Hedbergd5859e22011-01-25 01:19:58 +0200550 hci_setup_event_mask(hdev);
551
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200552 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200553 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
554
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200555 if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
556 test_bit(HCI_MGMT, &hdev->dev_flags)) {
557 struct hci_cp_write_local_name cp;
558
559 memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
560 hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp);
561 }
562
Johan Hedberg54d04db2012-02-22 15:47:48 +0200563 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
564 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
565 u8 mode = 0x01;
566 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
567 sizeof(mode), &mode);
568 } else {
569 struct hci_cp_write_eir cp;
570
571 memset(hdev->eir, 0, sizeof(hdev->eir));
572 memset(&cp, 0, sizeof(cp));
573
574 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
575 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200576 }
577
578 if (hdev->features[3] & LMP_RSSI_INQ)
579 hci_setup_inquiry_mode(hdev);
580
581 if (hdev->features[7] & LMP_INQ_TX_PWR)
582 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300583
584 if (hdev->features[7] & LMP_EXTFEATURES) {
585 struct hci_cp_read_local_ext_features cp;
586
587 cp.page = 0x01;
588 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
589 sizeof(cp), &cp);
590 }
Andre Guedese6100a22011-06-30 19:20:54 -0300591
Johan Hedberg47990ea2012-02-22 11:58:37 +0200592 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
593 u8 enable = 1;
594 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE,
595 sizeof(enable), &enable);
596 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200597}
598
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200599static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
600{
601 struct hci_rp_read_local_version *rp = (void *) skb->data;
602
603 BT_DBG("%s status 0x%x", hdev->name, rp->status);
604
605 if (rp->status)
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200606 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200607
608 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200609 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200610 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200611 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200612 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200613
614 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
615 hdev->manufacturer,
616 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200617
618 if (test_bit(HCI_INIT, &hdev->flags))
619 hci_setup(hdev);
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200620
621done:
622 hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200623}
624
625static void hci_setup_link_policy(struct hci_dev *hdev)
626{
627 u16 link_policy = 0;
628
629 if (hdev->features[0] & LMP_RSWITCH)
630 link_policy |= HCI_LP_RSWITCH;
631 if (hdev->features[0] & LMP_HOLD)
632 link_policy |= HCI_LP_HOLD;
633 if (hdev->features[0] & LMP_SNIFF)
634 link_policy |= HCI_LP_SNIFF;
635 if (hdev->features[1] & LMP_PARK)
636 link_policy |= HCI_LP_PARK;
637
638 link_policy = cpu_to_le16(link_policy);
639 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
640 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200641}
642
643static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
644{
645 struct hci_rp_read_local_commands *rp = (void *) skb->data;
646
647 BT_DBG("%s status 0x%x", hdev->name, rp->status);
648
649 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200650 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200651
652 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200653
654 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
655 hci_setup_link_policy(hdev);
656
657done:
658 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200659}
660
661static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
662{
663 struct hci_rp_read_local_features *rp = (void *) skb->data;
664
665 BT_DBG("%s status 0x%x", hdev->name, rp->status);
666
667 if (rp->status)
668 return;
669
670 memcpy(hdev->features, rp->features, 8);
671
672 /* Adjust default settings according to features
673 * supported by device. */
674
675 if (hdev->features[0] & LMP_3SLOT)
676 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
677
678 if (hdev->features[0] & LMP_5SLOT)
679 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
680
681 if (hdev->features[1] & LMP_HV2) {
682 hdev->pkt_type |= (HCI_HV2);
683 hdev->esco_type |= (ESCO_HV2);
684 }
685
686 if (hdev->features[1] & LMP_HV3) {
687 hdev->pkt_type |= (HCI_HV3);
688 hdev->esco_type |= (ESCO_HV3);
689 }
690
691 if (hdev->features[3] & LMP_ESCO)
692 hdev->esco_type |= (ESCO_EV3);
693
694 if (hdev->features[4] & LMP_EV4)
695 hdev->esco_type |= (ESCO_EV4);
696
697 if (hdev->features[4] & LMP_EV5)
698 hdev->esco_type |= (ESCO_EV5);
699
Marcel Holtmannefc76882009-02-06 09:13:37 +0100700 if (hdev->features[5] & LMP_EDR_ESCO_2M)
701 hdev->esco_type |= (ESCO_2EV3);
702
703 if (hdev->features[5] & LMP_EDR_ESCO_3M)
704 hdev->esco_type |= (ESCO_3EV3);
705
706 if (hdev->features[5] & LMP_EDR_3S_ESCO)
707 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
708
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200709 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
710 hdev->features[0], hdev->features[1],
711 hdev->features[2], hdev->features[3],
712 hdev->features[4], hdev->features[5],
713 hdev->features[6], hdev->features[7]);
714}
715
Johan Hedberg8f984df2012-02-28 01:07:22 +0200716static void hci_set_le_support(struct hci_dev *hdev)
717{
718 struct hci_cp_write_le_host_supported cp;
719
720 memset(&cp, 0, sizeof(cp));
721
722 if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
723 cp.le = 1;
724 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
725 }
726
727 if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE))
728 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED,
729 sizeof(cp), &cp);
730}
731
Andre Guedes971e3a42011-06-30 19:20:52 -0300732static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
733 struct sk_buff *skb)
734{
735 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
736
737 BT_DBG("%s status 0x%x", hdev->name, rp->status);
738
739 if (rp->status)
Johan Hedberg8f984df2012-02-28 01:07:22 +0200740 goto done;
Andre Guedes971e3a42011-06-30 19:20:52 -0300741
Andre Guedesb5b32b62011-12-30 10:34:04 -0300742 switch (rp->page) {
743 case 0:
744 memcpy(hdev->features, rp->features, 8);
745 break;
746 case 1:
747 memcpy(hdev->host_features, rp->features, 8);
748 break;
749 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300750
Johan Hedberg8f984df2012-02-28 01:07:22 +0200751 if (test_bit(HCI_INIT, &hdev->flags) && hdev->features[4] & LMP_LE)
752 hci_set_le_support(hdev);
753
754done:
Andre Guedes971e3a42011-06-30 19:20:52 -0300755 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
756}
757
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200758static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
759 struct sk_buff *skb)
760{
761 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
762
763 BT_DBG("%s status 0x%x", hdev->name, rp->status);
764
765 if (rp->status)
766 return;
767
768 hdev->flow_ctl_mode = rp->mode;
769
770 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
771}
772
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200773static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
774{
775 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
776
777 BT_DBG("%s status 0x%x", hdev->name, rp->status);
778
779 if (rp->status)
780 return;
781
782 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
783 hdev->sco_mtu = rp->sco_mtu;
784 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
785 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
786
787 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
788 hdev->sco_mtu = 64;
789 hdev->sco_pkts = 8;
790 }
791
792 hdev->acl_cnt = hdev->acl_pkts;
793 hdev->sco_cnt = hdev->sco_pkts;
794
795 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
796 hdev->acl_mtu, hdev->acl_pkts,
797 hdev->sco_mtu, hdev->sco_pkts);
798}
799
800static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
801{
802 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
803
804 BT_DBG("%s status 0x%x", hdev->name, rp->status);
805
806 if (!rp->status)
807 bacpy(&hdev->bdaddr, &rp->bdaddr);
808
Johan Hedberg23bb5762010-12-21 23:01:27 +0200809 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
810}
811
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200812static void hci_cc_read_data_block_size(struct hci_dev *hdev,
813 struct sk_buff *skb)
814{
815 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
816
817 BT_DBG("%s status 0x%x", hdev->name, rp->status);
818
819 if (rp->status)
820 return;
821
822 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
823 hdev->block_len = __le16_to_cpu(rp->block_len);
824 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
825
826 hdev->block_cnt = hdev->num_blocks;
827
828 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
829 hdev->block_cnt, hdev->block_len);
830
831 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
832}
833
Johan Hedberg23bb5762010-12-21 23:01:27 +0200834static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
835{
836 __u8 status = *((__u8 *) skb->data);
837
838 BT_DBG("%s status 0x%x", hdev->name, status);
839
840 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200841}
842
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300843static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
844 struct sk_buff *skb)
845{
846 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
847
848 BT_DBG("%s status 0x%x", hdev->name, rp->status);
849
850 if (rp->status)
851 return;
852
853 hdev->amp_status = rp->amp_status;
854 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
855 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
856 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
857 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
858 hdev->amp_type = rp->amp_type;
859 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
860 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
861 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
862 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
863
864 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
865}
866
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200867static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
868 struct sk_buff *skb)
869{
870 __u8 status = *((__u8 *) skb->data);
871
872 BT_DBG("%s status 0x%x", hdev->name, status);
873
874 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
875}
876
Johan Hedbergd5859e22011-01-25 01:19:58 +0200877static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
878{
879 __u8 status = *((__u8 *) skb->data);
880
881 BT_DBG("%s status 0x%x", hdev->name, status);
882
883 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
884}
885
886static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
887 struct sk_buff *skb)
888{
889 __u8 status = *((__u8 *) skb->data);
890
891 BT_DBG("%s status 0x%x", hdev->name, status);
892
893 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
894}
895
896static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
897 struct sk_buff *skb)
898{
899 __u8 status = *((__u8 *) skb->data);
900
901 BT_DBG("%s status 0x%x", hdev->name, status);
902
903 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
904}
905
906static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
907{
908 __u8 status = *((__u8 *) skb->data);
909
910 BT_DBG("%s status 0x%x", hdev->name, status);
911
912 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
913}
914
Johan Hedberg980e1a52011-01-22 06:10:07 +0200915static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
916{
917 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
918 struct hci_cp_pin_code_reply *cp;
919 struct hci_conn *conn;
920
921 BT_DBG("%s status 0x%x", hdev->name, rp->status);
922
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200923 hci_dev_lock(hdev);
924
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200925 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200926 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200927
928 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200929 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200930
931 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
932 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200933 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200934
935 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
936 if (conn)
937 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200938
939unlock:
940 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200941}
942
943static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
944{
945 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
946
947 BT_DBG("%s status 0x%x", hdev->name, rp->status);
948
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200949 hci_dev_lock(hdev);
950
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200951 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200952 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200953 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200954
955 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200956}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200957
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300958static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
959 struct sk_buff *skb)
960{
961 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
962
963 BT_DBG("%s status 0x%x", hdev->name, rp->status);
964
965 if (rp->status)
966 return;
967
968 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
969 hdev->le_pkts = rp->le_max_pkt;
970
971 hdev->le_cnt = hdev->le_pkts;
972
973 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
974
975 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
976}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200977
Johan Hedberga5c29682011-02-19 12:05:57 -0300978static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
979{
980 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
981
982 BT_DBG("%s status 0x%x", hdev->name, rp->status);
983
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200984 hci_dev_lock(hdev);
985
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200986 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200987 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
988 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200989
990 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300991}
992
993static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
994 struct sk_buff *skb)
995{
996 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
997
998 BT_DBG("%s status 0x%x", hdev->name, rp->status);
999
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001000 hci_dev_lock(hdev);
1001
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001002 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001003 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001004 ACL_LINK, 0,
Johan Hedberga5c29682011-02-19 12:05:57 -03001005 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001006
1007 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -03001008}
1009
Brian Gix1143d452011-11-23 08:28:34 -08001010static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
1011{
1012 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1013
1014 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1015
1016 hci_dev_lock(hdev);
1017
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001018 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001019 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1020 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001021
1022 hci_dev_unlock(hdev);
1023}
1024
1025static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1026 struct sk_buff *skb)
1027{
1028 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1029
1030 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1031
1032 hci_dev_lock(hdev);
1033
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001034 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001035 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001036 ACL_LINK, 0,
Brian Gix1143d452011-11-23 08:28:34 -08001037 rp->status);
1038
1039 hci_dev_unlock(hdev);
1040}
1041
Szymon Jancc35938b2011-03-22 13:12:21 +01001042static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1043 struct sk_buff *skb)
1044{
1045 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1046
1047 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1048
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001049 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001050 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001051 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001052 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001053}
1054
Andre Guedes07f7fa52011-12-02 21:13:31 +09001055static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1056{
1057 __u8 status = *((__u8 *) skb->data);
1058
1059 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001060
1061 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001062
1063 if (status) {
1064 hci_dev_lock(hdev);
1065 mgmt_start_discovery_failed(hdev, status);
1066 hci_dev_unlock(hdev);
1067 return;
1068 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001069}
1070
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001071static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1072 struct sk_buff *skb)
1073{
1074 struct hci_cp_le_set_scan_enable *cp;
1075 __u8 status = *((__u8 *) skb->data);
1076
1077 BT_DBG("%s status 0x%x", hdev->name, status);
1078
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001079 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1080 if (!cp)
1081 return;
1082
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001083 switch (cp->enable) {
1084 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001085 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1086
Andre Guedes3fd24152012-02-03 17:48:01 -03001087 if (status) {
1088 hci_dev_lock(hdev);
1089 mgmt_start_discovery_failed(hdev, status);
1090 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001091 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001092 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001093
Andre Guedesd23264a2011-11-25 20:53:38 -03001094 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1095
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001096 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001097
1098 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001099 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001100 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001101 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001102 break;
1103
1104 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001105 if (status)
1106 return;
1107
Andre Guedesd23264a2011-11-25 20:53:38 -03001108 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1109
Andre Guedesd0843292012-01-02 19:18:11 -03001110 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001111
1112 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1113 mgmt_interleaved_discovery(hdev);
1114 } else {
1115 hci_dev_lock(hdev);
1116 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1117 hci_dev_unlock(hdev);
1118 }
1119
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001120 break;
1121
1122 default:
1123 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1124 break;
Andre Guedes35815082011-05-26 16:23:53 -03001125 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001126}
1127
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001128static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1129{
1130 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1131
1132 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1133
1134 if (rp->status)
1135 return;
1136
1137 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1138}
1139
1140static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1141{
1142 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1143
1144 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1145
1146 if (rp->status)
1147 return;
1148
1149 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1150}
1151
Andre Guedesf9b49302011-06-30 19:20:53 -03001152static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1153 struct sk_buff *skb)
1154{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001155 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001156 __u8 status = *((__u8 *) skb->data);
1157
1158 BT_DBG("%s status 0x%x", hdev->name, status);
1159
Johan Hedberg06199cf2012-02-22 16:37:11 +02001160 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001161 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001162 return;
1163
Johan Hedberg8f984df2012-02-28 01:07:22 +02001164 if (!status) {
1165 if (sent->le)
1166 hdev->host_features[0] |= LMP_HOST_LE;
1167 else
1168 hdev->host_features[0] &= ~LMP_HOST_LE;
1169 }
1170
1171 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
1172 !test_bit(HCI_INIT, &hdev->flags))
1173 mgmt_le_enable_complete(hdev, sent->le, status);
1174
1175 hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001176}
1177
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001178static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1179{
1180 BT_DBG("%s status 0x%x", hdev->name, status);
1181
1182 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001183 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001184 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001185 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001186 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001187 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001188 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001189 return;
1190 }
1191
Andre Guedes89352e72011-11-04 14:16:53 -03001192 set_bit(HCI_INQUIRY, &hdev->flags);
1193
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001194 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001195 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001196 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001197}
1198
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1200{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001201 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001204 BT_DBG("%s status 0x%x", hdev->name, status);
1205
1206 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 if (!cp)
1208 return;
1209
1210 hci_dev_lock(hdev);
1211
1212 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1213
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001214 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215
1216 if (status) {
1217 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001218 if (status != 0x0c || conn->attempt > 2) {
1219 conn->state = BT_CLOSED;
1220 hci_proto_connect_cfm(conn, status);
1221 hci_conn_del(conn);
1222 } else
1223 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 }
1225 } else {
1226 if (!conn) {
1227 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1228 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001229 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230 conn->link_mode |= HCI_LM_MASTER;
1231 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001232 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 }
1234 }
1235
1236 hci_dev_unlock(hdev);
1237}
1238
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001239static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001241 struct hci_cp_add_sco *cp;
1242 struct hci_conn *acl, *sco;
1243 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001245 BT_DBG("%s status 0x%x", hdev->name, status);
1246
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001247 if (!status)
1248 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001250 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1251 if (!cp)
1252 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001254 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001256 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001257
1258 hci_dev_lock(hdev);
1259
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001260 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001261 if (acl) {
1262 sco = acl->link;
1263 if (sco) {
1264 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001265
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001266 hci_proto_connect_cfm(sco, status);
1267 hci_conn_del(sco);
1268 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001269 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001270
1271 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272}
1273
Marcel Holtmannf8558552008-07-14 20:13:49 +02001274static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1275{
1276 struct hci_cp_auth_requested *cp;
1277 struct hci_conn *conn;
1278
1279 BT_DBG("%s status 0x%x", hdev->name, status);
1280
1281 if (!status)
1282 return;
1283
1284 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1285 if (!cp)
1286 return;
1287
1288 hci_dev_lock(hdev);
1289
1290 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1291 if (conn) {
1292 if (conn->state == BT_CONFIG) {
1293 hci_proto_connect_cfm(conn, status);
1294 hci_conn_put(conn);
1295 }
1296 }
1297
1298 hci_dev_unlock(hdev);
1299}
1300
1301static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1302{
1303 struct hci_cp_set_conn_encrypt *cp;
1304 struct hci_conn *conn;
1305
1306 BT_DBG("%s status 0x%x", hdev->name, status);
1307
1308 if (!status)
1309 return;
1310
1311 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1312 if (!cp)
1313 return;
1314
1315 hci_dev_lock(hdev);
1316
1317 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1318 if (conn) {
1319 if (conn->state == BT_CONFIG) {
1320 hci_proto_connect_cfm(conn, status);
1321 hci_conn_put(conn);
1322 }
1323 }
1324
1325 hci_dev_unlock(hdev);
1326}
1327
Johan Hedberg127178d2010-11-18 22:22:29 +02001328static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001329 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001330{
Johan Hedberg392599b2010-11-18 22:22:28 +02001331 if (conn->state != BT_CONFIG || !conn->out)
1332 return 0;
1333
Johan Hedberg765c2a92011-01-19 12:06:52 +05301334 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001335 return 0;
1336
1337 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001338 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001339 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001340 conn->pending_sec_level != BT_SECURITY_HIGH &&
1341 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001342 return 0;
1343
Johan Hedberg392599b2010-11-18 22:22:28 +02001344 return 1;
1345}
1346
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001347static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1348{
1349 struct hci_cp_remote_name_req cp;
1350
1351 memset(&cp, 0, sizeof(cp));
1352
1353 bacpy(&cp.bdaddr, &e->data.bdaddr);
1354 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1355 cp.pscan_mode = e->data.pscan_mode;
1356 cp.clock_offset = e->data.clock_offset;
1357
1358 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1359}
1360
Johan Hedbergb644ba32012-01-17 21:48:47 +02001361static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001362{
1363 struct discovery_state *discov = &hdev->discovery;
1364 struct inquiry_entry *e;
1365
Johan Hedbergb644ba32012-01-17 21:48:47 +02001366 if (list_empty(&discov->resolve))
1367 return false;
1368
1369 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1370 if (hci_resolve_name(hdev, e) == 0) {
1371 e->name_state = NAME_PENDING;
1372 return true;
1373 }
1374
1375 return false;
1376}
1377
1378static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1379 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1380{
1381 struct discovery_state *discov = &hdev->discovery;
1382 struct inquiry_entry *e;
1383
1384 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Johan Hedberg08c79b62012-02-23 22:31:51 +02001385 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0,
Johan Hedbergb644ba32012-01-17 21:48:47 +02001386 name, name_len, conn->dev_class);
1387
1388 if (discov->state == DISCOVERY_STOPPED)
1389 return;
1390
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001391 if (discov->state == DISCOVERY_STOPPING)
1392 goto discov_complete;
1393
1394 if (discov->state != DISCOVERY_RESOLVING)
1395 return;
1396
1397 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1398 if (e) {
1399 e->name_state = NAME_KNOWN;
1400 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001401 if (name)
1402 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1403 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001404 }
1405
Johan Hedbergb644ba32012-01-17 21:48:47 +02001406 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001407 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001408
1409discov_complete:
1410 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1411}
1412
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001413static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1414{
Johan Hedberg127178d2010-11-18 22:22:29 +02001415 struct hci_cp_remote_name_req *cp;
1416 struct hci_conn *conn;
1417
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001418 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001419
1420 /* If successful wait for the name req complete event before
1421 * checking for the need to do authentication */
1422 if (!status)
1423 return;
1424
1425 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1426 if (!cp)
1427 return;
1428
1429 hci_dev_lock(hdev);
1430
1431 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001432
1433 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1434 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1435
Johan Hedberg79c6c702011-04-28 11:28:55 -07001436 if (!conn)
1437 goto unlock;
1438
1439 if (!hci_outgoing_auth_needed(hdev, conn))
1440 goto unlock;
1441
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001442 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001443 struct hci_cp_auth_requested cp;
1444 cp.handle = __cpu_to_le16(conn->handle);
1445 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1446 }
1447
Johan Hedberg79c6c702011-04-28 11:28:55 -07001448unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001449 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001450}
1451
Marcel Holtmann769be972008-07-14 20:13:49 +02001452static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1453{
1454 struct hci_cp_read_remote_features *cp;
1455 struct hci_conn *conn;
1456
1457 BT_DBG("%s status 0x%x", hdev->name, status);
1458
1459 if (!status)
1460 return;
1461
1462 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1463 if (!cp)
1464 return;
1465
1466 hci_dev_lock(hdev);
1467
1468 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1469 if (conn) {
1470 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001471 hci_proto_connect_cfm(conn, status);
1472 hci_conn_put(conn);
1473 }
1474 }
1475
1476 hci_dev_unlock(hdev);
1477}
1478
1479static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1480{
1481 struct hci_cp_read_remote_ext_features *cp;
1482 struct hci_conn *conn;
1483
1484 BT_DBG("%s status 0x%x", hdev->name, status);
1485
1486 if (!status)
1487 return;
1488
1489 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1490 if (!cp)
1491 return;
1492
1493 hci_dev_lock(hdev);
1494
1495 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1496 if (conn) {
1497 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001498 hci_proto_connect_cfm(conn, status);
1499 hci_conn_put(conn);
1500 }
1501 }
1502
1503 hci_dev_unlock(hdev);
1504}
1505
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001506static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1507{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001508 struct hci_cp_setup_sync_conn *cp;
1509 struct hci_conn *acl, *sco;
1510 __u16 handle;
1511
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001512 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001513
1514 if (!status)
1515 return;
1516
1517 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1518 if (!cp)
1519 return;
1520
1521 handle = __le16_to_cpu(cp->handle);
1522
1523 BT_DBG("%s handle %d", hdev->name, handle);
1524
1525 hci_dev_lock(hdev);
1526
1527 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001528 if (acl) {
1529 sco = acl->link;
1530 if (sco) {
1531 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001532
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001533 hci_proto_connect_cfm(sco, status);
1534 hci_conn_del(sco);
1535 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001536 }
1537
1538 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001539}
1540
1541static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1542{
1543 struct hci_cp_sniff_mode *cp;
1544 struct hci_conn *conn;
1545
1546 BT_DBG("%s status 0x%x", hdev->name, status);
1547
1548 if (!status)
1549 return;
1550
1551 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1552 if (!cp)
1553 return;
1554
1555 hci_dev_lock(hdev);
1556
1557 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001558 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001559 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001560
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001561 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001562 hci_sco_setup(conn, status);
1563 }
1564
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001565 hci_dev_unlock(hdev);
1566}
1567
1568static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1569{
1570 struct hci_cp_exit_sniff_mode *cp;
1571 struct hci_conn *conn;
1572
1573 BT_DBG("%s status 0x%x", hdev->name, status);
1574
1575 if (!status)
1576 return;
1577
1578 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1579 if (!cp)
1580 return;
1581
1582 hci_dev_lock(hdev);
1583
1584 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001585 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001586 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001587
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001588 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001589 hci_sco_setup(conn, status);
1590 }
1591
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001592 hci_dev_unlock(hdev);
1593}
1594
Johan Hedberg88c3df12012-02-09 14:27:38 +02001595static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1596{
1597 struct hci_cp_disconnect *cp;
1598 struct hci_conn *conn;
1599
1600 if (!status)
1601 return;
1602
1603 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1604 if (!cp)
1605 return;
1606
1607 hci_dev_lock(hdev);
1608
1609 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1610 if (conn)
1611 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1612 conn->dst_type, status);
1613
1614 hci_dev_unlock(hdev);
1615}
1616
Ville Tervofcd89c02011-02-10 22:38:47 -03001617static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1618{
1619 struct hci_cp_le_create_conn *cp;
1620 struct hci_conn *conn;
1621
1622 BT_DBG("%s status 0x%x", hdev->name, status);
1623
1624 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1625 if (!cp)
1626 return;
1627
1628 hci_dev_lock(hdev);
1629
1630 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1631
1632 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1633 conn);
1634
1635 if (status) {
1636 if (conn && conn->state == BT_CONNECT) {
1637 conn->state = BT_CLOSED;
1638 hci_proto_connect_cfm(conn, status);
1639 hci_conn_del(conn);
1640 }
1641 } else {
1642 if (!conn) {
1643 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001644 if (conn) {
1645 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001646 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001647 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001648 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001649 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001650 }
1651 }
1652
1653 hci_dev_unlock(hdev);
1654}
1655
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001656static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1657{
1658 BT_DBG("%s status 0x%x", hdev->name, status);
1659}
1660
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001661static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1662{
1663 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001664 struct discovery_state *discov = &hdev->discovery;
1665 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001666
1667 BT_DBG("%s status %d", hdev->name, status);
1668
Johan Hedberg23bb5762010-12-21 23:01:27 +02001669 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001670
1671 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001672
1673 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1674 return;
1675
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001676 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001677 return;
1678
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001679 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001680
Andre Guedes343f9352012-02-17 20:39:37 -03001681 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001682 goto unlock;
1683
1684 if (list_empty(&discov->resolve)) {
1685 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1686 goto unlock;
1687 }
1688
1689 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1690 if (e && hci_resolve_name(hdev, e) == 0) {
1691 e->name_state = NAME_PENDING;
1692 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1693 } else {
1694 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1695 }
1696
1697unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001698 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001699}
1700
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1702{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001703 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001704 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 int num_rsp = *((__u8 *) skb->data);
1706
1707 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1708
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001709 if (!num_rsp)
1710 return;
1711
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001713
Johan Hedberge17acd42011-03-30 23:57:16 +03001714 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001715 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001716
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 bacpy(&data.bdaddr, &info->bdaddr);
1718 data.pscan_rep_mode = info->pscan_rep_mode;
1719 data.pscan_period_mode = info->pscan_period_mode;
1720 data.pscan_mode = info->pscan_mode;
1721 memcpy(data.dev_class, info->dev_class, 3);
1722 data.clock_offset = info->clock_offset;
1723 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001724 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001725
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001726 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001727 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001728 info->dev_class, 0, !name_known, ssp,
Andre Guedes7d262f82012-01-10 18:20:49 -03001729 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001731
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 hci_dev_unlock(hdev);
1733}
1734
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001735static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001737 struct hci_ev_conn_complete *ev = (void *) skb->data;
1738 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001740 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001741
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001743
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001744 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001745 if (!conn) {
1746 if (ev->link_type != SCO_LINK)
1747 goto unlock;
1748
1749 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1750 if (!conn)
1751 goto unlock;
1752
1753 conn->type = SCO_LINK;
1754 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001755
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001756 if (!ev->status) {
1757 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001758
1759 if (conn->type == ACL_LINK) {
1760 conn->state = BT_CONFIG;
1761 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001762 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001763 } else
1764 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001765
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001766 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001767 hci_conn_add_sysfs(conn);
1768
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001769 if (test_bit(HCI_AUTH, &hdev->flags))
1770 conn->link_mode |= HCI_LM_AUTH;
1771
1772 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1773 conn->link_mode |= HCI_LM_ENCRYPT;
1774
1775 /* Get remote features */
1776 if (conn->type == ACL_LINK) {
1777 struct hci_cp_read_remote_features cp;
1778 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001779 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1780 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001781 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001782
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001783 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001784 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001785 struct hci_cp_change_conn_ptype cp;
1786 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001787 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1788 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1789 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001790 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001791 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001792 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001793 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001794 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001795 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001796 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001797
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001798 if (conn->type == ACL_LINK)
1799 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001800
Marcel Holtmann769be972008-07-14 20:13:49 +02001801 if (ev->status) {
1802 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001803 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001804 } else if (ev->link_type != ACL_LINK)
1805 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001806
1807unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001809
1810 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811}
1812
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1814{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001815 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 int mask = hdev->link_mode;
1817
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001818 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1819 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820
1821 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1822
Szymon Janc138d22e2011-02-17 16:44:23 +01001823 if ((mask & HCI_LM_ACCEPT) &&
1824 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001826 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828
1829 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001830
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001831 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1832 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001833 memcpy(ie->data.dev_class, ev->dev_class, 3);
1834
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1836 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001837 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1838 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001839 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 hci_dev_unlock(hdev);
1841 return;
1842 }
1843 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001844
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 memcpy(conn->dev_class, ev->dev_class, 3);
1846 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001847
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 hci_dev_unlock(hdev);
1849
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001850 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1851 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001853 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001855 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1856 cp.role = 0x00; /* Become master */
1857 else
1858 cp.role = 0x01; /* Remain slave */
1859
1860 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1861 sizeof(cp), &cp);
1862 } else {
1863 struct hci_cp_accept_sync_conn_req cp;
1864
1865 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001866 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001867
1868 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1869 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1870 cp.max_latency = cpu_to_le16(0xffff);
1871 cp.content_format = cpu_to_le16(hdev->voice_setting);
1872 cp.retrans_effort = 0xff;
1873
1874 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1875 sizeof(cp), &cp);
1876 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 } else {
1878 /* Connection rejected */
1879 struct hci_cp_reject_conn_req cp;
1880
1881 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001882 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001883 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 }
1885}
1886
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1888{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001889 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001890 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891
1892 BT_DBG("%s status %d", hdev->name, ev->status);
1893
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 hci_dev_lock(hdev);
1895
Marcel Holtmann04837f62006-07-03 10:02:33 +02001896 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001897 if (!conn)
1898 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001899
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001900 if (ev->status == 0)
1901 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902
Johan Hedbergb644ba32012-01-17 21:48:47 +02001903 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1904 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001905 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001906 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1907 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001908 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001909 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001910 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001911 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001912
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001913 if (ev->status == 0) {
1914 hci_proto_disconn_cfm(conn, ev->reason);
1915 hci_conn_del(conn);
1916 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001917
1918unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 hci_dev_unlock(hdev);
1920}
1921
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001922static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1923{
1924 struct hci_ev_auth_complete *ev = (void *) skb->data;
1925 struct hci_conn *conn;
1926
1927 BT_DBG("%s status %d", hdev->name, ev->status);
1928
1929 hci_dev_lock(hdev);
1930
1931 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001932 if (!conn)
1933 goto unlock;
1934
1935 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001936 if (!hci_conn_ssp_enabled(conn) &&
1937 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001938 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001939 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001940 conn->link_mode |= HCI_LM_AUTH;
1941 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001942 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001943 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001944 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
1945 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001946 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001947
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001948 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1949 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001950
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001951 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001952 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001953 struct hci_cp_set_conn_encrypt cp;
1954 cp.handle = ev->handle;
1955 cp.encrypt = 0x01;
1956 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1957 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001958 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001959 conn->state = BT_CONNECTED;
1960 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001961 hci_conn_put(conn);
1962 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001963 } else {
1964 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001965
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001966 hci_conn_hold(conn);
1967 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1968 hci_conn_put(conn);
1969 }
1970
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001971 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001972 if (!ev->status) {
1973 struct hci_cp_set_conn_encrypt cp;
1974 cp.handle = ev->handle;
1975 cp.encrypt = 0x01;
1976 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1977 &cp);
1978 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001979 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001980 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001981 }
1982 }
1983
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001984unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001985 hci_dev_unlock(hdev);
1986}
1987
1988static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1989{
Johan Hedberg127178d2010-11-18 22:22:29 +02001990 struct hci_ev_remote_name *ev = (void *) skb->data;
1991 struct hci_conn *conn;
1992
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001993 BT_DBG("%s", hdev->name);
1994
1995 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001996
1997 hci_dev_lock(hdev);
1998
1999 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002000
2001 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2002 goto check_auth;
2003
2004 if (ev->status == 0)
2005 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
2006 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
2007 else
2008 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2009
2010check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002011 if (!conn)
2012 goto unlock;
2013
2014 if (!hci_outgoing_auth_needed(hdev, conn))
2015 goto unlock;
2016
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002017 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002018 struct hci_cp_auth_requested cp;
2019 cp.handle = __cpu_to_le16(conn->handle);
2020 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2021 }
2022
Johan Hedberg79c6c702011-04-28 11:28:55 -07002023unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002024 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002025}
2026
2027static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2028{
2029 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2030 struct hci_conn *conn;
2031
2032 BT_DBG("%s status %d", hdev->name, ev->status);
2033
2034 hci_dev_lock(hdev);
2035
2036 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2037 if (conn) {
2038 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002039 if (ev->encrypt) {
2040 /* Encryption implies authentication */
2041 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002042 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002043 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002044 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002045 conn->link_mode &= ~HCI_LM_ENCRYPT;
2046 }
2047
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002048 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002049
Marcel Holtmannf8558552008-07-14 20:13:49 +02002050 if (conn->state == BT_CONFIG) {
2051 if (!ev->status)
2052 conn->state = BT_CONNECTED;
2053
2054 hci_proto_connect_cfm(conn, ev->status);
2055 hci_conn_put(conn);
2056 } else
2057 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002058 }
2059
2060 hci_dev_unlock(hdev);
2061}
2062
2063static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2064{
2065 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2066 struct hci_conn *conn;
2067
2068 BT_DBG("%s status %d", hdev->name, ev->status);
2069
2070 hci_dev_lock(hdev);
2071
2072 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2073 if (conn) {
2074 if (!ev->status)
2075 conn->link_mode |= HCI_LM_SECURE;
2076
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002077 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002078
2079 hci_key_change_cfm(conn, ev->status);
2080 }
2081
2082 hci_dev_unlock(hdev);
2083}
2084
2085static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2086{
2087 struct hci_ev_remote_features *ev = (void *) skb->data;
2088 struct hci_conn *conn;
2089
2090 BT_DBG("%s status %d", hdev->name, ev->status);
2091
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002092 hci_dev_lock(hdev);
2093
2094 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002095 if (!conn)
2096 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002097
Johan Hedbergccd556f2010-11-10 17:11:51 +02002098 if (!ev->status)
2099 memcpy(conn->features, ev->features, 8);
2100
2101 if (conn->state != BT_CONFIG)
2102 goto unlock;
2103
2104 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2105 struct hci_cp_read_remote_ext_features cp;
2106 cp.handle = ev->handle;
2107 cp.page = 0x01;
2108 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002109 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002110 goto unlock;
2111 }
2112
Johan Hedberg127178d2010-11-18 22:22:29 +02002113 if (!ev->status) {
2114 struct hci_cp_remote_name_req cp;
2115 memset(&cp, 0, sizeof(cp));
2116 bacpy(&cp.bdaddr, &conn->dst);
2117 cp.pscan_rep_mode = 0x02;
2118 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002119 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2120 mgmt_device_connected(hdev, &conn->dst, conn->type,
Johan Hedberg08c79b62012-02-23 22:31:51 +02002121 conn->dst_type, 0, NULL, 0,
Johan Hedbergb644ba32012-01-17 21:48:47 +02002122 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002123
Johan Hedberg127178d2010-11-18 22:22:29 +02002124 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002125 conn->state = BT_CONNECTED;
2126 hci_proto_connect_cfm(conn, ev->status);
2127 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002128 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002129
Johan Hedbergccd556f2010-11-10 17:11:51 +02002130unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002131 hci_dev_unlock(hdev);
2132}
2133
2134static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2135{
2136 BT_DBG("%s", hdev->name);
2137}
2138
2139static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2140{
2141 BT_DBG("%s", hdev->name);
2142}
2143
2144static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2145{
2146 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2147 __u16 opcode;
2148
2149 skb_pull(skb, sizeof(*ev));
2150
2151 opcode = __le16_to_cpu(ev->opcode);
2152
2153 switch (opcode) {
2154 case HCI_OP_INQUIRY_CANCEL:
2155 hci_cc_inquiry_cancel(hdev, skb);
2156 break;
2157
2158 case HCI_OP_EXIT_PERIODIC_INQ:
2159 hci_cc_exit_periodic_inq(hdev, skb);
2160 break;
2161
2162 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2163 hci_cc_remote_name_req_cancel(hdev, skb);
2164 break;
2165
2166 case HCI_OP_ROLE_DISCOVERY:
2167 hci_cc_role_discovery(hdev, skb);
2168 break;
2169
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002170 case HCI_OP_READ_LINK_POLICY:
2171 hci_cc_read_link_policy(hdev, skb);
2172 break;
2173
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002174 case HCI_OP_WRITE_LINK_POLICY:
2175 hci_cc_write_link_policy(hdev, skb);
2176 break;
2177
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002178 case HCI_OP_READ_DEF_LINK_POLICY:
2179 hci_cc_read_def_link_policy(hdev, skb);
2180 break;
2181
2182 case HCI_OP_WRITE_DEF_LINK_POLICY:
2183 hci_cc_write_def_link_policy(hdev, skb);
2184 break;
2185
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002186 case HCI_OP_RESET:
2187 hci_cc_reset(hdev, skb);
2188 break;
2189
2190 case HCI_OP_WRITE_LOCAL_NAME:
2191 hci_cc_write_local_name(hdev, skb);
2192 break;
2193
2194 case HCI_OP_READ_LOCAL_NAME:
2195 hci_cc_read_local_name(hdev, skb);
2196 break;
2197
2198 case HCI_OP_WRITE_AUTH_ENABLE:
2199 hci_cc_write_auth_enable(hdev, skb);
2200 break;
2201
2202 case HCI_OP_WRITE_ENCRYPT_MODE:
2203 hci_cc_write_encrypt_mode(hdev, skb);
2204 break;
2205
2206 case HCI_OP_WRITE_SCAN_ENABLE:
2207 hci_cc_write_scan_enable(hdev, skb);
2208 break;
2209
2210 case HCI_OP_READ_CLASS_OF_DEV:
2211 hci_cc_read_class_of_dev(hdev, skb);
2212 break;
2213
2214 case HCI_OP_WRITE_CLASS_OF_DEV:
2215 hci_cc_write_class_of_dev(hdev, skb);
2216 break;
2217
2218 case HCI_OP_READ_VOICE_SETTING:
2219 hci_cc_read_voice_setting(hdev, skb);
2220 break;
2221
2222 case HCI_OP_WRITE_VOICE_SETTING:
2223 hci_cc_write_voice_setting(hdev, skb);
2224 break;
2225
2226 case HCI_OP_HOST_BUFFER_SIZE:
2227 hci_cc_host_buffer_size(hdev, skb);
2228 break;
2229
Marcel Holtmann333140b2008-07-14 20:13:48 +02002230 case HCI_OP_WRITE_SSP_MODE:
2231 hci_cc_write_ssp_mode(hdev, skb);
2232 break;
2233
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002234 case HCI_OP_READ_LOCAL_VERSION:
2235 hci_cc_read_local_version(hdev, skb);
2236 break;
2237
2238 case HCI_OP_READ_LOCAL_COMMANDS:
2239 hci_cc_read_local_commands(hdev, skb);
2240 break;
2241
2242 case HCI_OP_READ_LOCAL_FEATURES:
2243 hci_cc_read_local_features(hdev, skb);
2244 break;
2245
Andre Guedes971e3a42011-06-30 19:20:52 -03002246 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2247 hci_cc_read_local_ext_features(hdev, skb);
2248 break;
2249
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002250 case HCI_OP_READ_BUFFER_SIZE:
2251 hci_cc_read_buffer_size(hdev, skb);
2252 break;
2253
2254 case HCI_OP_READ_BD_ADDR:
2255 hci_cc_read_bd_addr(hdev, skb);
2256 break;
2257
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002258 case HCI_OP_READ_DATA_BLOCK_SIZE:
2259 hci_cc_read_data_block_size(hdev, skb);
2260 break;
2261
Johan Hedberg23bb5762010-12-21 23:01:27 +02002262 case HCI_OP_WRITE_CA_TIMEOUT:
2263 hci_cc_write_ca_timeout(hdev, skb);
2264 break;
2265
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002266 case HCI_OP_READ_FLOW_CONTROL_MODE:
2267 hci_cc_read_flow_control_mode(hdev, skb);
2268 break;
2269
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002270 case HCI_OP_READ_LOCAL_AMP_INFO:
2271 hci_cc_read_local_amp_info(hdev, skb);
2272 break;
2273
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002274 case HCI_OP_DELETE_STORED_LINK_KEY:
2275 hci_cc_delete_stored_link_key(hdev, skb);
2276 break;
2277
Johan Hedbergd5859e22011-01-25 01:19:58 +02002278 case HCI_OP_SET_EVENT_MASK:
2279 hci_cc_set_event_mask(hdev, skb);
2280 break;
2281
2282 case HCI_OP_WRITE_INQUIRY_MODE:
2283 hci_cc_write_inquiry_mode(hdev, skb);
2284 break;
2285
2286 case HCI_OP_READ_INQ_RSP_TX_POWER:
2287 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2288 break;
2289
2290 case HCI_OP_SET_EVENT_FLT:
2291 hci_cc_set_event_flt(hdev, skb);
2292 break;
2293
Johan Hedberg980e1a52011-01-22 06:10:07 +02002294 case HCI_OP_PIN_CODE_REPLY:
2295 hci_cc_pin_code_reply(hdev, skb);
2296 break;
2297
2298 case HCI_OP_PIN_CODE_NEG_REPLY:
2299 hci_cc_pin_code_neg_reply(hdev, skb);
2300 break;
2301
Szymon Jancc35938b2011-03-22 13:12:21 +01002302 case HCI_OP_READ_LOCAL_OOB_DATA:
2303 hci_cc_read_local_oob_data_reply(hdev, skb);
2304 break;
2305
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002306 case HCI_OP_LE_READ_BUFFER_SIZE:
2307 hci_cc_le_read_buffer_size(hdev, skb);
2308 break;
2309
Johan Hedberga5c29682011-02-19 12:05:57 -03002310 case HCI_OP_USER_CONFIRM_REPLY:
2311 hci_cc_user_confirm_reply(hdev, skb);
2312 break;
2313
2314 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2315 hci_cc_user_confirm_neg_reply(hdev, skb);
2316 break;
2317
Brian Gix1143d452011-11-23 08:28:34 -08002318 case HCI_OP_USER_PASSKEY_REPLY:
2319 hci_cc_user_passkey_reply(hdev, skb);
2320 break;
2321
2322 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2323 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002324
2325 case HCI_OP_LE_SET_SCAN_PARAM:
2326 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002327 break;
2328
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002329 case HCI_OP_LE_SET_SCAN_ENABLE:
2330 hci_cc_le_set_scan_enable(hdev, skb);
2331 break;
2332
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002333 case HCI_OP_LE_LTK_REPLY:
2334 hci_cc_le_ltk_reply(hdev, skb);
2335 break;
2336
2337 case HCI_OP_LE_LTK_NEG_REPLY:
2338 hci_cc_le_ltk_neg_reply(hdev, skb);
2339 break;
2340
Andre Guedesf9b49302011-06-30 19:20:53 -03002341 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2342 hci_cc_write_le_host_supported(hdev, skb);
2343 break;
2344
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002345 default:
2346 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2347 break;
2348 }
2349
Ville Tervo6bd32322011-02-16 16:32:41 +02002350 if (ev->opcode != HCI_OP_NOP)
2351 del_timer(&hdev->cmd_timer);
2352
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002353 if (ev->ncmd) {
2354 atomic_set(&hdev->cmd_cnt, 1);
2355 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002356 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002357 }
2358}
2359
2360static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2361{
2362 struct hci_ev_cmd_status *ev = (void *) skb->data;
2363 __u16 opcode;
2364
2365 skb_pull(skb, sizeof(*ev));
2366
2367 opcode = __le16_to_cpu(ev->opcode);
2368
2369 switch (opcode) {
2370 case HCI_OP_INQUIRY:
2371 hci_cs_inquiry(hdev, ev->status);
2372 break;
2373
2374 case HCI_OP_CREATE_CONN:
2375 hci_cs_create_conn(hdev, ev->status);
2376 break;
2377
2378 case HCI_OP_ADD_SCO:
2379 hci_cs_add_sco(hdev, ev->status);
2380 break;
2381
Marcel Holtmannf8558552008-07-14 20:13:49 +02002382 case HCI_OP_AUTH_REQUESTED:
2383 hci_cs_auth_requested(hdev, ev->status);
2384 break;
2385
2386 case HCI_OP_SET_CONN_ENCRYPT:
2387 hci_cs_set_conn_encrypt(hdev, ev->status);
2388 break;
2389
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002390 case HCI_OP_REMOTE_NAME_REQ:
2391 hci_cs_remote_name_req(hdev, ev->status);
2392 break;
2393
Marcel Holtmann769be972008-07-14 20:13:49 +02002394 case HCI_OP_READ_REMOTE_FEATURES:
2395 hci_cs_read_remote_features(hdev, ev->status);
2396 break;
2397
2398 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2399 hci_cs_read_remote_ext_features(hdev, ev->status);
2400 break;
2401
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002402 case HCI_OP_SETUP_SYNC_CONN:
2403 hci_cs_setup_sync_conn(hdev, ev->status);
2404 break;
2405
2406 case HCI_OP_SNIFF_MODE:
2407 hci_cs_sniff_mode(hdev, ev->status);
2408 break;
2409
2410 case HCI_OP_EXIT_SNIFF_MODE:
2411 hci_cs_exit_sniff_mode(hdev, ev->status);
2412 break;
2413
Johan Hedberg8962ee72011-01-20 12:40:27 +02002414 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002415 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002416 break;
2417
Ville Tervofcd89c02011-02-10 22:38:47 -03002418 case HCI_OP_LE_CREATE_CONN:
2419 hci_cs_le_create_conn(hdev, ev->status);
2420 break;
2421
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002422 case HCI_OP_LE_START_ENC:
2423 hci_cs_le_start_enc(hdev, ev->status);
2424 break;
2425
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002426 default:
2427 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2428 break;
2429 }
2430
Ville Tervo6bd32322011-02-16 16:32:41 +02002431 if (ev->opcode != HCI_OP_NOP)
2432 del_timer(&hdev->cmd_timer);
2433
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002434 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002435 atomic_set(&hdev->cmd_cnt, 1);
2436 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002437 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002438 }
2439}
2440
2441static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2442{
2443 struct hci_ev_role_change *ev = (void *) skb->data;
2444 struct hci_conn *conn;
2445
2446 BT_DBG("%s status %d", hdev->name, ev->status);
2447
2448 hci_dev_lock(hdev);
2449
2450 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2451 if (conn) {
2452 if (!ev->status) {
2453 if (ev->role)
2454 conn->link_mode &= ~HCI_LM_MASTER;
2455 else
2456 conn->link_mode |= HCI_LM_MASTER;
2457 }
2458
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002459 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002460
2461 hci_role_switch_cfm(conn, ev->status, ev->role);
2462 }
2463
2464 hci_dev_unlock(hdev);
2465}
2466
Linus Torvalds1da177e2005-04-16 15:20:36 -07002467static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2468{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002469 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002470 int i;
2471
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002472 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2473 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2474 return;
2475 }
2476
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002477 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2478 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002479 BT_DBG("%s bad parameters", hdev->name);
2480 return;
2481 }
2482
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002483 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2484
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002485 for (i = 0; i < ev->num_hndl; i++) {
2486 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487 struct hci_conn *conn;
2488 __u16 handle, count;
2489
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002490 handle = __le16_to_cpu(info->handle);
2491 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002492
2493 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002494 if (!conn)
2495 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002497 conn->sent -= count;
2498
2499 switch (conn->type) {
2500 case ACL_LINK:
2501 hdev->acl_cnt += count;
2502 if (hdev->acl_cnt > hdev->acl_pkts)
2503 hdev->acl_cnt = hdev->acl_pkts;
2504 break;
2505
2506 case LE_LINK:
2507 if (hdev->le_pkts) {
2508 hdev->le_cnt += count;
2509 if (hdev->le_cnt > hdev->le_pkts)
2510 hdev->le_cnt = hdev->le_pkts;
2511 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002512 hdev->acl_cnt += count;
2513 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002514 hdev->acl_cnt = hdev->acl_pkts;
2515 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002516 break;
2517
2518 case SCO_LINK:
2519 hdev->sco_cnt += count;
2520 if (hdev->sco_cnt > hdev->sco_pkts)
2521 hdev->sco_cnt = hdev->sco_pkts;
2522 break;
2523
2524 default:
2525 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2526 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527 }
2528 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002529
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002530 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002531}
2532
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002533static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2534 struct sk_buff *skb)
2535{
2536 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2537 int i;
2538
2539 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2540 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2541 return;
2542 }
2543
2544 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2545 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2546 BT_DBG("%s bad parameters", hdev->name);
2547 return;
2548 }
2549
2550 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2551 ev->num_hndl);
2552
2553 for (i = 0; i < ev->num_hndl; i++) {
2554 struct hci_comp_blocks_info *info = &ev->handles[i];
2555 struct hci_conn *conn;
2556 __u16 handle, block_count;
2557
2558 handle = __le16_to_cpu(info->handle);
2559 block_count = __le16_to_cpu(info->blocks);
2560
2561 conn = hci_conn_hash_lookup_handle(hdev, handle);
2562 if (!conn)
2563 continue;
2564
2565 conn->sent -= block_count;
2566
2567 switch (conn->type) {
2568 case ACL_LINK:
2569 hdev->block_cnt += block_count;
2570 if (hdev->block_cnt > hdev->num_blocks)
2571 hdev->block_cnt = hdev->num_blocks;
2572 break;
2573
2574 default:
2575 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2576 break;
2577 }
2578 }
2579
2580 queue_work(hdev->workqueue, &hdev->tx_work);
2581}
2582
Marcel Holtmann04837f62006-07-03 10:02:33 +02002583static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002584{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002585 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002586 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587
2588 BT_DBG("%s status %d", hdev->name, ev->status);
2589
2590 hci_dev_lock(hdev);
2591
Marcel Holtmann04837f62006-07-03 10:02:33 +02002592 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2593 if (conn) {
2594 conn->mode = ev->mode;
2595 conn->interval = __le16_to_cpu(ev->interval);
2596
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002597 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002598 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002599 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002600 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002601 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002602 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002603
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002604 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002605 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002606 }
2607
2608 hci_dev_unlock(hdev);
2609}
2610
Linus Torvalds1da177e2005-04-16 15:20:36 -07002611static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2612{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002613 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2614 struct hci_conn *conn;
2615
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002616 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002617
2618 hci_dev_lock(hdev);
2619
2620 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002621 if (!conn)
2622 goto unlock;
2623
2624 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002625 hci_conn_hold(conn);
2626 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2627 hci_conn_put(conn);
2628 }
2629
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002630 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002631 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2632 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002633 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002634 u8 secure;
2635
2636 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2637 secure = 1;
2638 else
2639 secure = 0;
2640
Johan Hedberg744cf192011-11-08 20:40:14 +02002641 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002642 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002643
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002644unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002645 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646}
2647
Linus Torvalds1da177e2005-04-16 15:20:36 -07002648static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2649{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002650 struct hci_ev_link_key_req *ev = (void *) skb->data;
2651 struct hci_cp_link_key_reply cp;
2652 struct hci_conn *conn;
2653 struct link_key *key;
2654
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002655 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002656
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002657 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002658 return;
2659
2660 hci_dev_lock(hdev);
2661
2662 key = hci_find_link_key(hdev, &ev->bdaddr);
2663 if (!key) {
2664 BT_DBG("%s link key not found for %s", hdev->name,
2665 batostr(&ev->bdaddr));
2666 goto not_found;
2667 }
2668
2669 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2670 batostr(&ev->bdaddr));
2671
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002672 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002673 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002674 BT_DBG("%s ignoring debug key", hdev->name);
2675 goto not_found;
2676 }
2677
2678 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002679 if (conn) {
2680 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2681 conn->auth_type != 0xff &&
2682 (conn->auth_type & 0x01)) {
2683 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2684 goto not_found;
2685 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002686
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002687 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2688 conn->pending_sec_level == BT_SECURITY_HIGH) {
2689 BT_DBG("%s ignoring key unauthenticated for high \
2690 security", hdev->name);
2691 goto not_found;
2692 }
2693
2694 conn->key_type = key->type;
2695 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002696 }
2697
2698 bacpy(&cp.bdaddr, &ev->bdaddr);
2699 memcpy(cp.link_key, key->val, 16);
2700
2701 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2702
2703 hci_dev_unlock(hdev);
2704
2705 return;
2706
2707not_found:
2708 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2709 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710}
2711
Linus Torvalds1da177e2005-04-16 15:20:36 -07002712static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2713{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002714 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2715 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002716 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002717
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002718 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002719
2720 hci_dev_lock(hdev);
2721
2722 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2723 if (conn) {
2724 hci_conn_hold(conn);
2725 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002726 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002727
2728 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2729 conn->key_type = ev->key_type;
2730
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002731 hci_conn_put(conn);
2732 }
2733
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002734 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002735 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002736 ev->key_type, pin_len);
2737
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002738 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002739}
2740
Marcel Holtmann04837f62006-07-03 10:02:33 +02002741static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2742{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002743 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002744 struct hci_conn *conn;
2745
2746 BT_DBG("%s status %d", hdev->name, ev->status);
2747
2748 hci_dev_lock(hdev);
2749
2750 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751 if (conn && !ev->status) {
2752 struct inquiry_entry *ie;
2753
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002754 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2755 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756 ie->data.clock_offset = ev->clock_offset;
2757 ie->timestamp = jiffies;
2758 }
2759 }
2760
2761 hci_dev_unlock(hdev);
2762}
2763
Marcel Holtmanna8746412008-07-14 20:13:46 +02002764static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2765{
2766 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2767 struct hci_conn *conn;
2768
2769 BT_DBG("%s status %d", hdev->name, ev->status);
2770
2771 hci_dev_lock(hdev);
2772
2773 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2774 if (conn && !ev->status)
2775 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2776
2777 hci_dev_unlock(hdev);
2778}
2779
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002780static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2781{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002782 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002783 struct inquiry_entry *ie;
2784
2785 BT_DBG("%s", hdev->name);
2786
2787 hci_dev_lock(hdev);
2788
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002789 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2790 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002791 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2792 ie->timestamp = jiffies;
2793 }
2794
2795 hci_dev_unlock(hdev);
2796}
2797
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002798static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2799{
2800 struct inquiry_data data;
2801 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002802 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002803
2804 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2805
2806 if (!num_rsp)
2807 return;
2808
2809 hci_dev_lock(hdev);
2810
2811 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002812 struct inquiry_info_with_rssi_and_pscan_mode *info;
2813 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002814
Johan Hedberge17acd42011-03-30 23:57:16 +03002815 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002816 bacpy(&data.bdaddr, &info->bdaddr);
2817 data.pscan_rep_mode = info->pscan_rep_mode;
2818 data.pscan_period_mode = info->pscan_period_mode;
2819 data.pscan_mode = info->pscan_mode;
2820 memcpy(data.dev_class, info->dev_class, 3);
2821 data.clock_offset = info->clock_offset;
2822 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002823 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002824
2825 name_known = hci_inquiry_cache_update(hdev, &data,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002826 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002827 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002828 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002829 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002830 }
2831 } else {
2832 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2833
Johan Hedberge17acd42011-03-30 23:57:16 +03002834 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002835 bacpy(&data.bdaddr, &info->bdaddr);
2836 data.pscan_rep_mode = info->pscan_rep_mode;
2837 data.pscan_period_mode = info->pscan_period_mode;
2838 data.pscan_mode = 0x00;
2839 memcpy(data.dev_class, info->dev_class, 3);
2840 data.clock_offset = info->clock_offset;
2841 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002842 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002843 name_known = hci_inquiry_cache_update(hdev, &data,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002844 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002845 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002846 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002847 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002848 }
2849 }
2850
2851 hci_dev_unlock(hdev);
2852}
2853
2854static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2855{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002856 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2857 struct hci_conn *conn;
2858
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002859 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002860
Marcel Holtmann41a96212008-07-14 20:13:48 +02002861 hci_dev_lock(hdev);
2862
2863 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002864 if (!conn)
2865 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002866
Johan Hedbergccd556f2010-11-10 17:11:51 +02002867 if (!ev->status && ev->page == 0x01) {
2868 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002869
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002870 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2871 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002872 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002873
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002874 if (ev->features[0] & LMP_HOST_SSP)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002875 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002876 }
2877
Johan Hedbergccd556f2010-11-10 17:11:51 +02002878 if (conn->state != BT_CONFIG)
2879 goto unlock;
2880
Johan Hedberg127178d2010-11-18 22:22:29 +02002881 if (!ev->status) {
2882 struct hci_cp_remote_name_req cp;
2883 memset(&cp, 0, sizeof(cp));
2884 bacpy(&cp.bdaddr, &conn->dst);
2885 cp.pscan_rep_mode = 0x02;
2886 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002887 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2888 mgmt_device_connected(hdev, &conn->dst, conn->type,
Johan Hedberg08c79b62012-02-23 22:31:51 +02002889 conn->dst_type, 0, NULL, 0,
Johan Hedbergb644ba32012-01-17 21:48:47 +02002890 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002891
Johan Hedberg127178d2010-11-18 22:22:29 +02002892 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002893 conn->state = BT_CONNECTED;
2894 hci_proto_connect_cfm(conn, ev->status);
2895 hci_conn_put(conn);
2896 }
2897
2898unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002899 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002900}
2901
2902static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2903{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002904 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2905 struct hci_conn *conn;
2906
2907 BT_DBG("%s status %d", hdev->name, ev->status);
2908
2909 hci_dev_lock(hdev);
2910
2911 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002912 if (!conn) {
2913 if (ev->link_type == ESCO_LINK)
2914 goto unlock;
2915
2916 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2917 if (!conn)
2918 goto unlock;
2919
2920 conn->type = SCO_LINK;
2921 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002922
Marcel Holtmann732547f2009-04-19 19:14:14 +02002923 switch (ev->status) {
2924 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002925 conn->handle = __le16_to_cpu(ev->handle);
2926 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002927
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002928 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002929 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002930 break;
2931
Stephen Coe705e5712010-02-16 11:29:44 -05002932 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002933 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002934 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002935 case 0x1f: /* Unspecified error */
2936 if (conn->out && conn->attempt < 2) {
2937 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2938 (hdev->esco_type & EDR_ESCO_MASK);
2939 hci_setup_sync(conn, conn->link->handle);
2940 goto unlock;
2941 }
2942 /* fall through */
2943
2944 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002945 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002946 break;
2947 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002948
2949 hci_proto_connect_cfm(conn, ev->status);
2950 if (ev->status)
2951 hci_conn_del(conn);
2952
2953unlock:
2954 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002955}
2956
2957static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2958{
2959 BT_DBG("%s", hdev->name);
2960}
2961
Marcel Holtmann04837f62006-07-03 10:02:33 +02002962static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2963{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002964 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002965
2966 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002967}
2968
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002969static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2970{
2971 struct inquiry_data data;
2972 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2973 int num_rsp = *((__u8 *) skb->data);
2974
2975 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2976
2977 if (!num_rsp)
2978 return;
2979
2980 hci_dev_lock(hdev);
2981
Johan Hedberge17acd42011-03-30 23:57:16 +03002982 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002983 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002984
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002985 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002986 data.pscan_rep_mode = info->pscan_rep_mode;
2987 data.pscan_period_mode = info->pscan_period_mode;
2988 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002989 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002990 data.clock_offset = info->clock_offset;
2991 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002992 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002993
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002994 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002995 name_known = eir_has_data_type(info->data,
2996 sizeof(info->data),
2997 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002998 else
2999 name_known = true;
3000
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003001 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
3002 &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003003 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02003004 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003005 !name_known, ssp, info->data,
Andre Guedes7d262f82012-01-10 18:20:49 -03003006 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003007 }
3008
3009 hci_dev_unlock(hdev);
3010}
3011
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003012static inline u8 hci_get_auth_req(struct hci_conn *conn)
3013{
3014 /* If remote requests dedicated bonding follow that lead */
3015 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3016 /* If both remote and local IO capabilities allow MITM
3017 * protection then require it, otherwise don't */
3018 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3019 return 0x02;
3020 else
3021 return 0x03;
3022 }
3023
3024 /* If remote requests no-bonding follow that lead */
3025 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003026 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003027
3028 return conn->auth_type;
3029}
3030
Marcel Holtmann04936842008-07-14 20:13:48 +02003031static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3032{
3033 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3034 struct hci_conn *conn;
3035
3036 BT_DBG("%s", hdev->name);
3037
3038 hci_dev_lock(hdev);
3039
3040 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003041 if (!conn)
3042 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003043
Johan Hedberg03b555e2011-01-04 15:40:05 +02003044 hci_conn_hold(conn);
3045
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003046 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003047 goto unlock;
3048
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003049 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003050 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003051 struct hci_cp_io_capability_reply cp;
3052
3053 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303054 /* Change the IO capability from KeyboardDisplay
3055 * to DisplayYesNo as it is not supported by BT spec. */
3056 cp.capability = (conn->io_capability == 0x04) ?
3057 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003058 conn->auth_type = hci_get_auth_req(conn);
3059 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003060
Johan Hedberg58a681e2012-01-16 06:47:28 +02003061 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003062 hci_find_remote_oob_data(hdev, &conn->dst))
3063 cp.oob_data = 0x01;
3064 else
3065 cp.oob_data = 0x00;
3066
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003067 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3068 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003069 } else {
3070 struct hci_cp_io_capability_neg_reply cp;
3071
3072 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003073 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003074
3075 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3076 sizeof(cp), &cp);
3077 }
3078
3079unlock:
3080 hci_dev_unlock(hdev);
3081}
3082
3083static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3084{
3085 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3086 struct hci_conn *conn;
3087
3088 BT_DBG("%s", hdev->name);
3089
3090 hci_dev_lock(hdev);
3091
3092 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3093 if (!conn)
3094 goto unlock;
3095
Johan Hedberg03b555e2011-01-04 15:40:05 +02003096 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003097 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003098 if (ev->oob_data)
3099 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003100
3101unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003102 hci_dev_unlock(hdev);
3103}
3104
Johan Hedberga5c29682011-02-19 12:05:57 -03003105static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3106 struct sk_buff *skb)
3107{
3108 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003109 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003110 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003111
3112 BT_DBG("%s", hdev->name);
3113
3114 hci_dev_lock(hdev);
3115
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003116 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003117 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003118
Johan Hedberg7a828902011-04-28 11:28:53 -07003119 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3120 if (!conn)
3121 goto unlock;
3122
3123 loc_mitm = (conn->auth_type & 0x01);
3124 rem_mitm = (conn->remote_auth & 0x01);
3125
3126 /* If we require MITM but the remote device can't provide that
3127 * (it has NoInputNoOutput) then reject the confirmation
3128 * request. The only exception is when we're dedicated bonding
3129 * initiators (connect_cfm_cb set) since then we always have the MITM
3130 * bit set. */
3131 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3132 BT_DBG("Rejecting request: remote device can't provide MITM");
3133 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3134 sizeof(ev->bdaddr), &ev->bdaddr);
3135 goto unlock;
3136 }
3137
3138 /* If no side requires MITM protection; auto-accept */
3139 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3140 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003141
3142 /* If we're not the initiators request authorization to
3143 * proceed from user space (mgmt_user_confirm with
3144 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003145 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003146 BT_DBG("Confirming auto-accept as acceptor");
3147 confirm_hint = 1;
3148 goto confirm;
3149 }
3150
Johan Hedberg9f616562011-04-28 11:28:54 -07003151 BT_DBG("Auto-accept of user confirmation with %ums delay",
3152 hdev->auto_accept_delay);
3153
3154 if (hdev->auto_accept_delay > 0) {
3155 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3156 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3157 goto unlock;
3158 }
3159
Johan Hedberg7a828902011-04-28 11:28:53 -07003160 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3161 sizeof(ev->bdaddr), &ev->bdaddr);
3162 goto unlock;
3163 }
3164
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003165confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003166 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003167 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003168
3169unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003170 hci_dev_unlock(hdev);
3171}
3172
Brian Gix1143d452011-11-23 08:28:34 -08003173static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3174 struct sk_buff *skb)
3175{
3176 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3177
3178 BT_DBG("%s", hdev->name);
3179
3180 hci_dev_lock(hdev);
3181
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003182 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003183 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003184
3185 hci_dev_unlock(hdev);
3186}
3187
Marcel Holtmann04936842008-07-14 20:13:48 +02003188static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3189{
3190 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3191 struct hci_conn *conn;
3192
3193 BT_DBG("%s", hdev->name);
3194
3195 hci_dev_lock(hdev);
3196
3197 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003198 if (!conn)
3199 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003200
Johan Hedberg2a611692011-02-19 12:06:00 -03003201 /* To avoid duplicate auth_failed events to user space we check
3202 * the HCI_CONN_AUTH_PEND flag which will be set if we
3203 * initiated the authentication. A traditional auth_complete
3204 * event gets always produced as initiator and is also mapped to
3205 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003206 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003207 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3208 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003209
3210 hci_conn_put(conn);
3211
3212unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003213 hci_dev_unlock(hdev);
3214}
3215
Marcel Holtmann41a96212008-07-14 20:13:48 +02003216static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3217{
3218 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3219 struct inquiry_entry *ie;
3220
3221 BT_DBG("%s", hdev->name);
3222
3223 hci_dev_lock(hdev);
3224
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003225 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3226 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003227 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003228
3229 hci_dev_unlock(hdev);
3230}
3231
Szymon Janc2763eda2011-03-22 13:12:22 +01003232static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3233 struct sk_buff *skb)
3234{
3235 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3236 struct oob_data *data;
3237
3238 BT_DBG("%s", hdev->name);
3239
3240 hci_dev_lock(hdev);
3241
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003242 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003243 goto unlock;
3244
Szymon Janc2763eda2011-03-22 13:12:22 +01003245 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3246 if (data) {
3247 struct hci_cp_remote_oob_data_reply cp;
3248
3249 bacpy(&cp.bdaddr, &ev->bdaddr);
3250 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3251 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3252
3253 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3254 &cp);
3255 } else {
3256 struct hci_cp_remote_oob_data_neg_reply cp;
3257
3258 bacpy(&cp.bdaddr, &ev->bdaddr);
3259 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3260 &cp);
3261 }
3262
Szymon Jance1ba1f12011-04-06 13:01:59 +02003263unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003264 hci_dev_unlock(hdev);
3265}
3266
Ville Tervofcd89c02011-02-10 22:38:47 -03003267static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3268{
3269 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3270 struct hci_conn *conn;
3271
3272 BT_DBG("%s status %d", hdev->name, ev->status);
3273
3274 hci_dev_lock(hdev);
3275
3276 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003277 if (!conn) {
3278 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3279 if (!conn) {
3280 BT_ERR("No memory for new connection");
3281 hci_dev_unlock(hdev);
3282 return;
3283 }
Andre Guedes29b79882011-05-31 14:20:54 -03003284
3285 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003286 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003287
3288 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003289 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3290 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003291 hci_proto_connect_cfm(conn, ev->status);
3292 conn->state = BT_CLOSED;
3293 hci_conn_del(conn);
3294 goto unlock;
3295 }
3296
Johan Hedbergb644ba32012-01-17 21:48:47 +02003297 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3298 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Johan Hedberg08c79b62012-02-23 22:31:51 +02003299 conn->dst_type, 0, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003300
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003301 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003302 conn->handle = __le16_to_cpu(ev->handle);
3303 conn->state = BT_CONNECTED;
3304
3305 hci_conn_hold_device(conn);
3306 hci_conn_add_sysfs(conn);
3307
3308 hci_proto_connect_cfm(conn, ev->status);
3309
3310unlock:
3311 hci_dev_unlock(hdev);
3312}
3313
Andre Guedes9aa04c92011-05-26 16:23:51 -03003314static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3315 struct sk_buff *skb)
3316{
Andre Guedese95beb42011-09-26 20:48:35 -03003317 u8 num_reports = skb->data[0];
3318 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003319 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003320
3321 hci_dev_lock(hdev);
3322
Andre Guedese95beb42011-09-26 20:48:35 -03003323 while (num_reports--) {
3324 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003325
Andre Guedes9aa04c92011-05-26 16:23:51 -03003326 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003327
Andre Guedes3c9e9192012-01-10 18:20:50 -03003328 rssi = ev->data[ev->length];
3329 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003330 NULL, rssi, 0, 1, ev->data,
3331 ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003332
Andre Guedese95beb42011-09-26 20:48:35 -03003333 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003334 }
3335
3336 hci_dev_unlock(hdev);
3337}
3338
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003339static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3340 struct sk_buff *skb)
3341{
3342 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3343 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003344 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003345 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003346 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003347
3348 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3349
3350 hci_dev_lock(hdev);
3351
3352 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003353 if (conn == NULL)
3354 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003355
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003356 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3357 if (ltk == NULL)
3358 goto not_found;
3359
3360 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003361 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003362
3363 if (ltk->authenticated)
3364 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003365
3366 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3367
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003368 if (ltk->type & HCI_SMP_STK) {
3369 list_del(&ltk->list);
3370 kfree(ltk);
3371 }
3372
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003373 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003374
3375 return;
3376
3377not_found:
3378 neg.handle = ev->handle;
3379 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3380 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003381}
3382
Ville Tervofcd89c02011-02-10 22:38:47 -03003383static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3384{
3385 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3386
3387 skb_pull(skb, sizeof(*le_ev));
3388
3389 switch (le_ev->subevent) {
3390 case HCI_EV_LE_CONN_COMPLETE:
3391 hci_le_conn_complete_evt(hdev, skb);
3392 break;
3393
Andre Guedes9aa04c92011-05-26 16:23:51 -03003394 case HCI_EV_LE_ADVERTISING_REPORT:
3395 hci_le_adv_report_evt(hdev, skb);
3396 break;
3397
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003398 case HCI_EV_LE_LTK_REQ:
3399 hci_le_ltk_request_evt(hdev, skb);
3400 break;
3401
Ville Tervofcd89c02011-02-10 22:38:47 -03003402 default:
3403 break;
3404 }
3405}
3406
Linus Torvalds1da177e2005-04-16 15:20:36 -07003407void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3408{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003409 struct hci_event_hdr *hdr = (void *) skb->data;
3410 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003411
3412 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3413
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003414 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003415 case HCI_EV_INQUIRY_COMPLETE:
3416 hci_inquiry_complete_evt(hdev, skb);
3417 break;
3418
3419 case HCI_EV_INQUIRY_RESULT:
3420 hci_inquiry_result_evt(hdev, skb);
3421 break;
3422
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003423 case HCI_EV_CONN_COMPLETE:
3424 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003425 break;
3426
Linus Torvalds1da177e2005-04-16 15:20:36 -07003427 case HCI_EV_CONN_REQUEST:
3428 hci_conn_request_evt(hdev, skb);
3429 break;
3430
Linus Torvalds1da177e2005-04-16 15:20:36 -07003431 case HCI_EV_DISCONN_COMPLETE:
3432 hci_disconn_complete_evt(hdev, skb);
3433 break;
3434
Linus Torvalds1da177e2005-04-16 15:20:36 -07003435 case HCI_EV_AUTH_COMPLETE:
3436 hci_auth_complete_evt(hdev, skb);
3437 break;
3438
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003439 case HCI_EV_REMOTE_NAME:
3440 hci_remote_name_evt(hdev, skb);
3441 break;
3442
Linus Torvalds1da177e2005-04-16 15:20:36 -07003443 case HCI_EV_ENCRYPT_CHANGE:
3444 hci_encrypt_change_evt(hdev, skb);
3445 break;
3446
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003447 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3448 hci_change_link_key_complete_evt(hdev, skb);
3449 break;
3450
3451 case HCI_EV_REMOTE_FEATURES:
3452 hci_remote_features_evt(hdev, skb);
3453 break;
3454
3455 case HCI_EV_REMOTE_VERSION:
3456 hci_remote_version_evt(hdev, skb);
3457 break;
3458
3459 case HCI_EV_QOS_SETUP_COMPLETE:
3460 hci_qos_setup_complete_evt(hdev, skb);
3461 break;
3462
3463 case HCI_EV_CMD_COMPLETE:
3464 hci_cmd_complete_evt(hdev, skb);
3465 break;
3466
3467 case HCI_EV_CMD_STATUS:
3468 hci_cmd_status_evt(hdev, skb);
3469 break;
3470
3471 case HCI_EV_ROLE_CHANGE:
3472 hci_role_change_evt(hdev, skb);
3473 break;
3474
3475 case HCI_EV_NUM_COMP_PKTS:
3476 hci_num_comp_pkts_evt(hdev, skb);
3477 break;
3478
3479 case HCI_EV_MODE_CHANGE:
3480 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003481 break;
3482
3483 case HCI_EV_PIN_CODE_REQ:
3484 hci_pin_code_request_evt(hdev, skb);
3485 break;
3486
3487 case HCI_EV_LINK_KEY_REQ:
3488 hci_link_key_request_evt(hdev, skb);
3489 break;
3490
3491 case HCI_EV_LINK_KEY_NOTIFY:
3492 hci_link_key_notify_evt(hdev, skb);
3493 break;
3494
3495 case HCI_EV_CLOCK_OFFSET:
3496 hci_clock_offset_evt(hdev, skb);
3497 break;
3498
Marcel Holtmanna8746412008-07-14 20:13:46 +02003499 case HCI_EV_PKT_TYPE_CHANGE:
3500 hci_pkt_type_change_evt(hdev, skb);
3501 break;
3502
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003503 case HCI_EV_PSCAN_REP_MODE:
3504 hci_pscan_rep_mode_evt(hdev, skb);
3505 break;
3506
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003507 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3508 hci_inquiry_result_with_rssi_evt(hdev, skb);
3509 break;
3510
3511 case HCI_EV_REMOTE_EXT_FEATURES:
3512 hci_remote_ext_features_evt(hdev, skb);
3513 break;
3514
3515 case HCI_EV_SYNC_CONN_COMPLETE:
3516 hci_sync_conn_complete_evt(hdev, skb);
3517 break;
3518
3519 case HCI_EV_SYNC_CONN_CHANGED:
3520 hci_sync_conn_changed_evt(hdev, skb);
3521 break;
3522
Marcel Holtmann04837f62006-07-03 10:02:33 +02003523 case HCI_EV_SNIFF_SUBRATE:
3524 hci_sniff_subrate_evt(hdev, skb);
3525 break;
3526
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003527 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3528 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003529 break;
3530
Marcel Holtmann04936842008-07-14 20:13:48 +02003531 case HCI_EV_IO_CAPA_REQUEST:
3532 hci_io_capa_request_evt(hdev, skb);
3533 break;
3534
Johan Hedberg03b555e2011-01-04 15:40:05 +02003535 case HCI_EV_IO_CAPA_REPLY:
3536 hci_io_capa_reply_evt(hdev, skb);
3537 break;
3538
Johan Hedberga5c29682011-02-19 12:05:57 -03003539 case HCI_EV_USER_CONFIRM_REQUEST:
3540 hci_user_confirm_request_evt(hdev, skb);
3541 break;
3542
Brian Gix1143d452011-11-23 08:28:34 -08003543 case HCI_EV_USER_PASSKEY_REQUEST:
3544 hci_user_passkey_request_evt(hdev, skb);
3545 break;
3546
Marcel Holtmann04936842008-07-14 20:13:48 +02003547 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3548 hci_simple_pair_complete_evt(hdev, skb);
3549 break;
3550
Marcel Holtmann41a96212008-07-14 20:13:48 +02003551 case HCI_EV_REMOTE_HOST_FEATURES:
3552 hci_remote_host_features_evt(hdev, skb);
3553 break;
3554
Ville Tervofcd89c02011-02-10 22:38:47 -03003555 case HCI_EV_LE_META:
3556 hci_le_meta_evt(hdev, skb);
3557 break;
3558
Szymon Janc2763eda2011-03-22 13:12:22 +01003559 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3560 hci_remote_oob_data_request_evt(hdev, skb);
3561 break;
3562
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003563 case HCI_EV_NUM_COMP_BLOCKS:
3564 hci_num_comp_blocks_evt(hdev, skb);
3565 break;
3566
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003567 default:
3568 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003569 break;
3570 }
3571
3572 kfree_skb(skb);
3573 hdev->stat.evt_rx++;
3574}