blob: a0fc1afb3ae45307509bcb7214b21278e1dc7e10 [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
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020040#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <asm/unaligned.h>
42
43#include <net/bluetooth/bluetooth.h>
44#include <net/bluetooth/hci_core.h>
45
Linus Torvalds1da177e2005-04-16 15:20:36 -070046/* Handle HCI Event packets */
47
Marcel Holtmanna9de9242007-10-20 13:33:56 +020048static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070049{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020050 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
Andre Guedese6d465c2011-11-09 17:14:26 -030054 if (status) {
55 hci_dev_lock(hdev);
56 mgmt_stop_discovery_failed(hdev, status);
57 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020058 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030059 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
Andre Guedes89352e72011-11-04 14:16:53 -030061 clear_bit(HCI_INQUIRY, &hdev->flags);
62
Johan Hedberg56e5cb82011-11-08 20:40:16 +020063 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020064 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020065 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010066
Johan Hedberg23bb5762010-12-21 23:01:27 +020067 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010068
Marcel Holtmanna9de9242007-10-20 13:33:56 +020069 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070070}
71
Andre Guedes4d934832012-03-21 00:03:35 -030072static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
73{
74 __u8 status = *((__u8 *) skb->data);
75
76 BT_DBG("%s status 0x%x", hdev->name, status);
77}
78
Marcel Holtmanna9de9242007-10-20 13:33:56 +020079static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070080{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020081 __u8 status = *((__u8 *) skb->data);
82
83 BT_DBG("%s status 0x%x", hdev->name, status);
84
85 if (status)
86 return;
87
Marcel Holtmanna9de9242007-10-20 13:33:56 +020088 hci_conn_check_pending(hdev);
89}
90
91static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
92{
93 BT_DBG("%s", hdev->name);
94}
95
96static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
97{
98 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200101 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200103 if (rp->status)
104 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200106 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200108 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
109 if (conn) {
110 if (rp->role)
111 conn->link_mode &= ~HCI_LM_MASTER;
112 else
113 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200115
116 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117}
118
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200119static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
120{
121 struct hci_rp_read_link_policy *rp = (void *) skb->data;
122 struct hci_conn *conn;
123
124 BT_DBG("%s status 0x%x", hdev->name, rp->status);
125
126 if (rp->status)
127 return;
128
129 hci_dev_lock(hdev);
130
131 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
132 if (conn)
133 conn->link_policy = __le16_to_cpu(rp->policy);
134
135 hci_dev_unlock(hdev);
136}
137
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200138static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200140 struct hci_rp_write_link_policy *rp = (void *) skb->data;
141 struct hci_conn *conn;
142 void *sent;
143
144 BT_DBG("%s status 0x%x", hdev->name, rp->status);
145
146 if (rp->status)
147 return;
148
149 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
150 if (!sent)
151 return;
152
153 hci_dev_lock(hdev);
154
155 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200156 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700157 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200158
159 hci_dev_unlock(hdev);
160}
161
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200162static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
163{
164 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
165
166 BT_DBG("%s status 0x%x", hdev->name, rp->status);
167
168 if (rp->status)
169 return;
170
171 hdev->link_policy = __le16_to_cpu(rp->policy);
172}
173
174static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
175{
176 __u8 status = *((__u8 *) skb->data);
177 void *sent;
178
179 BT_DBG("%s status 0x%x", hdev->name, status);
180
181 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
182 if (!sent)
183 return;
184
185 if (!status)
186 hdev->link_policy = get_unaligned_le16(sent);
187
Johan Hedberg23bb5762010-12-21 23:01:27 +0200188 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200189}
190
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200191static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
192{
193 __u8 status = *((__u8 *) skb->data);
194
195 BT_DBG("%s status 0x%x", hdev->name, status);
196
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300197 clear_bit(HCI_RESET, &hdev->flags);
198
Johan Hedberg23bb5762010-12-21 23:01:27 +0200199 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300200
Johan Hedberga297e972012-02-21 17:55:47 +0200201 /* Reset all non-persistent flags */
Johan Hedberg9f8ce962012-03-02 03:06:04 +0200202 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN) | BIT(HCI_PENDING_CLASS));
Andre Guedes69775ff2012-02-23 16:50:05 +0200203
204 hdev->discovery.state = DISCOVERY_STOPPED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200205}
206
207static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
208{
209 __u8 status = *((__u8 *) skb->data);
210 void *sent;
211
212 BT_DBG("%s status 0x%x", hdev->name, status);
213
214 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
215 if (!sent)
216 return;
217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 hci_dev_lock(hdev);
219
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200220 if (test_bit(HCI_MGMT, &hdev->dev_flags))
221 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200222 else if (!status)
223 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200224
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200225 hci_dev_unlock(hdev);
Johan Hedberg3159d382012-02-24 13:47:56 +0200226
227 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200228}
229
230static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
231{
232 struct hci_rp_read_local_name *rp = (void *) skb->data;
233
234 BT_DBG("%s status 0x%x", hdev->name, rp->status);
235
236 if (rp->status)
237 return;
238
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200239 if (test_bit(HCI_SETUP, &hdev->dev_flags))
240 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200241}
242
243static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
244{
245 __u8 status = *((__u8 *) skb->data);
246 void *sent;
247
248 BT_DBG("%s status 0x%x", hdev->name, status);
249
250 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
251 if (!sent)
252 return;
253
254 if (!status) {
255 __u8 param = *((__u8 *) sent);
256
257 if (param == AUTH_ENABLED)
258 set_bit(HCI_AUTH, &hdev->flags);
259 else
260 clear_bit(HCI_AUTH, &hdev->flags);
261 }
262
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200263 if (test_bit(HCI_MGMT, &hdev->dev_flags))
264 mgmt_auth_enable_complete(hdev, status);
265
Johan Hedberg23bb5762010-12-21 23:01:27 +0200266 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200267}
268
269static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
270{
271 __u8 status = *((__u8 *) skb->data);
272 void *sent;
273
274 BT_DBG("%s status 0x%x", hdev->name, status);
275
276 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
277 if (!sent)
278 return;
279
280 if (!status) {
281 __u8 param = *((__u8 *) sent);
282
283 if (param)
284 set_bit(HCI_ENCRYPT, &hdev->flags);
285 else
286 clear_bit(HCI_ENCRYPT, &hdev->flags);
287 }
288
Johan Hedberg23bb5762010-12-21 23:01:27 +0200289 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200290}
291
292static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
293{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200294 __u8 param, status = *((__u8 *) skb->data);
295 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200296 void *sent;
297
298 BT_DBG("%s status 0x%x", hdev->name, status);
299
300 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
301 if (!sent)
302 return;
303
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200304 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200305
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200306 hci_dev_lock(hdev);
307
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200308 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200309 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200310 hdev->discov_timeout = 0;
311 goto done;
312 }
313
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200314 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
315 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200316
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200317 if (param & SCAN_INQUIRY) {
318 set_bit(HCI_ISCAN, &hdev->flags);
319 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200320 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200321 if (hdev->discov_timeout > 0) {
322 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
323 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
324 to);
325 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200326 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200327 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200328
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200329 if (param & SCAN_PAGE) {
330 set_bit(HCI_PSCAN, &hdev->flags);
331 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200332 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200333 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200334 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200335
336done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200337 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200338 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200339}
340
341static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
342{
343 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
344
345 BT_DBG("%s status 0x%x", hdev->name, rp->status);
346
347 if (rp->status)
348 return;
349
350 memcpy(hdev->dev_class, rp->dev_class, 3);
351
352 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
353 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
354}
355
356static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
357{
358 __u8 status = *((__u8 *) skb->data);
359 void *sent;
360
361 BT_DBG("%s status 0x%x", hdev->name, status);
362
363 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
364 if (!sent)
365 return;
366
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100367 hci_dev_lock(hdev);
368
369 if (status == 0)
370 memcpy(hdev->dev_class, sent, 3);
371
372 if (test_bit(HCI_MGMT, &hdev->dev_flags))
373 mgmt_set_class_of_dev_complete(hdev, sent, status);
374
375 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200376}
377
378static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
379{
380 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200382
383 BT_DBG("%s status 0x%x", hdev->name, rp->status);
384
385 if (rp->status)
386 return;
387
388 setting = __le16_to_cpu(rp->voice_setting);
389
Marcel Holtmannf383f272008-07-14 20:13:47 +0200390 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200391 return;
392
393 hdev->voice_setting = setting;
394
395 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
396
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200397 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200398 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200399}
400
401static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
402{
403 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200404 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 void *sent;
406
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200407 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Marcel Holtmannf383f272008-07-14 20:13:47 +0200409 if (status)
410 return;
411
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200412 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
413 if (!sent)
414 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415
Marcel Holtmannf383f272008-07-14 20:13:47 +0200416 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
Marcel Holtmannf383f272008-07-14 20:13:47 +0200418 if (hdev->voice_setting == setting)
419 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
Marcel Holtmannf383f272008-07-14 20:13:47 +0200421 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422
Marcel Holtmannf383f272008-07-14 20:13:47 +0200423 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
424
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200425 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200426 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427}
428
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200429static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200431 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200433 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434
Johan Hedberg23bb5762010-12-21 23:01:27 +0200435 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436}
437
Marcel Holtmann333140b2008-07-14 20:13:48 +0200438static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
439{
440 __u8 status = *((__u8 *) skb->data);
441 void *sent;
442
443 BT_DBG("%s status 0x%x", hdev->name, status);
444
Marcel Holtmann333140b2008-07-14 20:13:48 +0200445 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
446 if (!sent)
447 return;
448
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200449 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200450 mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status);
451 else if (!status) {
452 if (*((u8 *) sent))
453 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
454 else
455 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
456 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200457}
458
Johan Hedbergd5859e22011-01-25 01:19:58 +0200459static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
460{
461 if (hdev->features[6] & LMP_EXT_INQ)
462 return 2;
463
464 if (hdev->features[3] & LMP_RSSI_INQ)
465 return 1;
466
467 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
468 hdev->lmp_subver == 0x0757)
469 return 1;
470
471 if (hdev->manufacturer == 15) {
472 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
473 return 1;
474 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
475 return 1;
476 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
477 return 1;
478 }
479
480 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
481 hdev->lmp_subver == 0x1805)
482 return 1;
483
484 return 0;
485}
486
487static void hci_setup_inquiry_mode(struct hci_dev *hdev)
488{
489 u8 mode;
490
491 mode = hci_get_inquiry_mode(hdev);
492
493 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
494}
495
496static void hci_setup_event_mask(struct hci_dev *hdev)
497{
498 /* The second byte is 0xff instead of 0x9f (two reserved bits
499 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
500 * command otherwise */
501 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
502
Ville Tervo6de6c182011-05-27 11:16:21 +0300503 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
504 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200505 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300506 return;
507
508 events[4] |= 0x01; /* Flow Specification Complete */
509 events[4] |= 0x02; /* Inquiry Result with RSSI */
510 events[4] |= 0x04; /* Read Remote Extended Features Complete */
511 events[5] |= 0x08; /* Synchronous Connection Complete */
512 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200513
514 if (hdev->features[3] & LMP_RSSI_INQ)
515 events[4] |= 0x04; /* Inquiry Result with RSSI */
516
517 if (hdev->features[5] & LMP_SNIFF_SUBR)
518 events[5] |= 0x20; /* Sniff Subrating */
519
520 if (hdev->features[5] & LMP_PAUSE_ENC)
521 events[5] |= 0x80; /* Encryption Key Refresh Complete */
522
523 if (hdev->features[6] & LMP_EXT_INQ)
524 events[5] |= 0x40; /* Extended Inquiry Result */
525
526 if (hdev->features[6] & LMP_NO_FLUSH)
527 events[7] |= 0x01; /* Enhanced Flush Complete */
528
529 if (hdev->features[7] & LMP_LSTO)
530 events[6] |= 0x80; /* Link Supervision Timeout Changed */
531
532 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
533 events[6] |= 0x01; /* IO Capability Request */
534 events[6] |= 0x02; /* IO Capability Response */
535 events[6] |= 0x04; /* User Confirmation Request */
536 events[6] |= 0x08; /* User Passkey Request */
537 events[6] |= 0x10; /* Remote OOB Data Request */
538 events[6] |= 0x20; /* Simple Pairing Complete */
539 events[7] |= 0x04; /* User Passkey Notification */
540 events[7] |= 0x08; /* Keypress Notification */
541 events[7] |= 0x10; /* Remote Host Supported
542 * Features Notification */
543 }
544
545 if (hdev->features[4] & LMP_LE)
546 events[7] |= 0x20; /* LE Meta-Event */
547
548 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
549}
550
551static void hci_setup(struct hci_dev *hdev)
552{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200553 if (hdev->dev_type != HCI_BREDR)
554 return;
555
Johan Hedbergd5859e22011-01-25 01:19:58 +0200556 hci_setup_event_mask(hdev);
557
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200558 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200559 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
560
Johan Hedberg54d04db2012-02-22 15:47:48 +0200561 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
562 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
563 u8 mode = 0x01;
564 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300565 sizeof(mode), &mode);
Johan Hedberg54d04db2012-02-22 15:47:48 +0200566 } else {
567 struct hci_cp_write_eir cp;
568
569 memset(hdev->eir, 0, sizeof(hdev->eir));
570 memset(&cp, 0, sizeof(cp));
571
572 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
573 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200574 }
575
576 if (hdev->features[3] & LMP_RSSI_INQ)
577 hci_setup_inquiry_mode(hdev);
578
579 if (hdev->features[7] & LMP_INQ_TX_PWR)
580 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300581
582 if (hdev->features[7] & LMP_EXTFEATURES) {
583 struct hci_cp_read_local_ext_features cp;
584
585 cp.page = 0x01;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300586 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp),
587 &cp);
Andre Guedes971e3a42011-06-30 19:20:52 -0300588 }
Andre Guedese6100a22011-06-30 19:20:54 -0300589
Johan Hedberg47990ea2012-02-22 11:58:37 +0200590 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
591 u8 enable = 1;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300592 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
593 &enable);
Johan Hedberg47990ea2012-02-22 11:58:37 +0200594 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200595}
596
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200597static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
598{
599 struct hci_rp_read_local_version *rp = (void *) skb->data;
600
601 BT_DBG("%s status 0x%x", hdev->name, rp->status);
602
603 if (rp->status)
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200604 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200605
606 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200607 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200608 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200609 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200610 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200611
612 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
613 hdev->manufacturer,
614 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200615
616 if (test_bit(HCI_INIT, &hdev->flags))
617 hci_setup(hdev);
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200618
619done:
620 hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200621}
622
623static void hci_setup_link_policy(struct hci_dev *hdev)
624{
Andrei Emeltchenko035100c2012-03-12 15:59:32 +0200625 struct hci_cp_write_def_link_policy cp;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200626 u16 link_policy = 0;
627
628 if (hdev->features[0] & LMP_RSWITCH)
629 link_policy |= HCI_LP_RSWITCH;
630 if (hdev->features[0] & LMP_HOLD)
631 link_policy |= HCI_LP_HOLD;
632 if (hdev->features[0] & LMP_SNIFF)
633 link_policy |= HCI_LP_SNIFF;
634 if (hdev->features[1] & LMP_PARK)
635 link_policy |= HCI_LP_PARK;
636
Andrei Emeltchenko035100c2012-03-12 15:59:32 +0200637 cp.policy = cpu_to_le16(link_policy);
638 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200639}
640
641static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
642{
643 struct hci_rp_read_local_commands *rp = (void *) skb->data;
644
645 BT_DBG("%s status 0x%x", hdev->name, rp->status);
646
647 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200648 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200649
650 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200651
652 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
653 hci_setup_link_policy(hdev);
654
655done:
656 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200657}
658
659static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
660{
661 struct hci_rp_read_local_features *rp = (void *) skb->data;
662
663 BT_DBG("%s status 0x%x", hdev->name, rp->status);
664
665 if (rp->status)
666 return;
667
668 memcpy(hdev->features, rp->features, 8);
669
670 /* Adjust default settings according to features
671 * supported by device. */
672
673 if (hdev->features[0] & LMP_3SLOT)
674 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
675
676 if (hdev->features[0] & LMP_5SLOT)
677 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
678
679 if (hdev->features[1] & LMP_HV2) {
680 hdev->pkt_type |= (HCI_HV2);
681 hdev->esco_type |= (ESCO_HV2);
682 }
683
684 if (hdev->features[1] & LMP_HV3) {
685 hdev->pkt_type |= (HCI_HV3);
686 hdev->esco_type |= (ESCO_HV3);
687 }
688
689 if (hdev->features[3] & LMP_ESCO)
690 hdev->esco_type |= (ESCO_EV3);
691
692 if (hdev->features[4] & LMP_EV4)
693 hdev->esco_type |= (ESCO_EV4);
694
695 if (hdev->features[4] & LMP_EV5)
696 hdev->esco_type |= (ESCO_EV5);
697
Marcel Holtmannefc76882009-02-06 09:13:37 +0100698 if (hdev->features[5] & LMP_EDR_ESCO_2M)
699 hdev->esco_type |= (ESCO_2EV3);
700
701 if (hdev->features[5] & LMP_EDR_ESCO_3M)
702 hdev->esco_type |= (ESCO_3EV3);
703
704 if (hdev->features[5] & LMP_EDR_3S_ESCO)
705 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
706
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200707 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
708 hdev->features[0], hdev->features[1],
709 hdev->features[2], hdev->features[3],
710 hdev->features[4], hdev->features[5],
711 hdev->features[6], hdev->features[7]);
712}
713
Johan Hedberg8f984df2012-02-28 01:07:22 +0200714static void hci_set_le_support(struct hci_dev *hdev)
715{
716 struct hci_cp_write_le_host_supported cp;
717
718 memset(&cp, 0, sizeof(cp));
719
720 if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
721 cp.le = 1;
722 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
723 }
724
725 if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300726 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
727 &cp);
Johan Hedberg8f984df2012-02-28 01:07:22 +0200728}
729
Andre Guedes971e3a42011-06-30 19:20:52 -0300730static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
731 struct sk_buff *skb)
732{
733 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
734
735 BT_DBG("%s status 0x%x", hdev->name, rp->status);
736
737 if (rp->status)
Johan Hedberg8f984df2012-02-28 01:07:22 +0200738 goto done;
Andre Guedes971e3a42011-06-30 19:20:52 -0300739
Andre Guedesb5b32b62011-12-30 10:34:04 -0300740 switch (rp->page) {
741 case 0:
742 memcpy(hdev->features, rp->features, 8);
743 break;
744 case 1:
745 memcpy(hdev->host_features, rp->features, 8);
746 break;
747 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300748
Johan Hedberg8f984df2012-02-28 01:07:22 +0200749 if (test_bit(HCI_INIT, &hdev->flags) && hdev->features[4] & LMP_LE)
750 hci_set_le_support(hdev);
751
752done:
Andre Guedes971e3a42011-06-30 19:20:52 -0300753 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
754}
755
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200756static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
757 struct sk_buff *skb)
758{
759 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
760
761 BT_DBG("%s status 0x%x", hdev->name, rp->status);
762
763 if (rp->status)
764 return;
765
766 hdev->flow_ctl_mode = rp->mode;
767
768 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
769}
770
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200771static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
772{
773 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
774
775 BT_DBG("%s status 0x%x", hdev->name, rp->status);
776
777 if (rp->status)
778 return;
779
780 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
781 hdev->sco_mtu = rp->sco_mtu;
782 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
783 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
784
785 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
786 hdev->sco_mtu = 64;
787 hdev->sco_pkts = 8;
788 }
789
790 hdev->acl_cnt = hdev->acl_pkts;
791 hdev->sco_cnt = hdev->sco_pkts;
792
793 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
794 hdev->acl_mtu, hdev->acl_pkts,
795 hdev->sco_mtu, hdev->sco_pkts);
796}
797
798static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
799{
800 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
801
802 BT_DBG("%s status 0x%x", hdev->name, rp->status);
803
804 if (!rp->status)
805 bacpy(&hdev->bdaddr, &rp->bdaddr);
806
Johan Hedberg23bb5762010-12-21 23:01:27 +0200807 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
808}
809
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200810static void hci_cc_read_data_block_size(struct hci_dev *hdev,
811 struct sk_buff *skb)
812{
813 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
814
815 BT_DBG("%s status 0x%x", hdev->name, rp->status);
816
817 if (rp->status)
818 return;
819
820 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
821 hdev->block_len = __le16_to_cpu(rp->block_len);
822 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
823
824 hdev->block_cnt = hdev->num_blocks;
825
826 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
827 hdev->block_cnt, hdev->block_len);
828
829 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
830}
831
Johan Hedberg23bb5762010-12-21 23:01:27 +0200832static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
833{
834 __u8 status = *((__u8 *) skb->data);
835
836 BT_DBG("%s status 0x%x", hdev->name, status);
837
838 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200839}
840
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300841static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
842 struct sk_buff *skb)
843{
844 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
845
846 BT_DBG("%s status 0x%x", hdev->name, rp->status);
847
848 if (rp->status)
849 return;
850
851 hdev->amp_status = rp->amp_status;
852 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
853 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
854 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
855 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
856 hdev->amp_type = rp->amp_type;
857 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
858 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
859 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
860 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
861
862 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
863}
864
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200865static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
866 struct sk_buff *skb)
867{
868 __u8 status = *((__u8 *) skb->data);
869
870 BT_DBG("%s status 0x%x", hdev->name, status);
871
872 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
873}
874
Johan Hedbergd5859e22011-01-25 01:19:58 +0200875static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
876{
877 __u8 status = *((__u8 *) skb->data);
878
879 BT_DBG("%s status 0x%x", hdev->name, status);
880
881 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
882}
883
884static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
885 struct sk_buff *skb)
886{
887 __u8 status = *((__u8 *) skb->data);
888
889 BT_DBG("%s status 0x%x", hdev->name, status);
890
891 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
892}
893
894static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
895 struct sk_buff *skb)
896{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700897 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200898
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700899 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200900
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700901 if (!rp->status)
902 hdev->inq_tx_power = rp->tx_power;
903
904 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200905}
906
907static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
908{
909 __u8 status = *((__u8 *) skb->data);
910
911 BT_DBG("%s status 0x%x", hdev->name, status);
912
913 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
914}
915
Johan Hedberg980e1a52011-01-22 06:10:07 +0200916static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
917{
918 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
919 struct hci_cp_pin_code_reply *cp;
920 struct hci_conn *conn;
921
922 BT_DBG("%s status 0x%x", hdev->name, rp->status);
923
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200924 hci_dev_lock(hdev);
925
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200926 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200927 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200928
929 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200930 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200931
932 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
933 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200934 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200935
936 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
937 if (conn)
938 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200939
940unlock:
941 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200942}
943
944static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
945{
946 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
947
948 BT_DBG("%s status 0x%x", hdev->name, rp->status);
949
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200950 hci_dev_lock(hdev);
951
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200952 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200953 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200954 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200955
956 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200957}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200958
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300959static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
960 struct sk_buff *skb)
961{
962 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
963
964 BT_DBG("%s status 0x%x", hdev->name, rp->status);
965
966 if (rp->status)
967 return;
968
969 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
970 hdev->le_pkts = rp->le_max_pkt;
971
972 hdev->le_cnt = hdev->le_pkts;
973
974 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
975
976 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
977}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200978
Johan Hedberga5c29682011-02-19 12:05:57 -0300979static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
980{
981 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
982
983 BT_DBG("%s status 0x%x", hdev->name, rp->status);
984
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200985 hci_dev_lock(hdev);
986
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200987 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300988 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
989 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200990
991 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300992}
993
994static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
995 struct sk_buff *skb)
996{
997 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
998
999 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1000
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001001 hci_dev_lock(hdev);
1002
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001003 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001004 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001005 ACL_LINK, 0, 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,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001020 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,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001036 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001037
1038 hci_dev_unlock(hdev);
1039}
1040
Szymon Jancc35938b2011-03-22 13:12:21 +01001041static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1042 struct sk_buff *skb)
1043{
1044 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1045
1046 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1047
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001048 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001049 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001050 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001051 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001052}
1053
Andre Guedes07f7fa52011-12-02 21:13:31 +09001054static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1055{
1056 __u8 status = *((__u8 *) skb->data);
1057
1058 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001059
1060 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001061
1062 if (status) {
1063 hci_dev_lock(hdev);
1064 mgmt_start_discovery_failed(hdev, status);
1065 hci_dev_unlock(hdev);
1066 return;
1067 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001068}
1069
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001070static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1071 struct sk_buff *skb)
1072{
1073 struct hci_cp_le_set_scan_enable *cp;
1074 __u8 status = *((__u8 *) skb->data);
1075
1076 BT_DBG("%s status 0x%x", hdev->name, status);
1077
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001078 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1079 if (!cp)
1080 return;
1081
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001082 switch (cp->enable) {
1083 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001084 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1085
Andre Guedes3fd24152012-02-03 17:48:01 -03001086 if (status) {
1087 hci_dev_lock(hdev);
1088 mgmt_start_discovery_failed(hdev, status);
1089 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001090 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001091 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001092
Andre Guedesd23264a2011-11-25 20:53:38 -03001093 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1094
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001095 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001096
1097 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001098 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001099 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001100 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001101 break;
1102
1103 case LE_SCANNING_DISABLED:
Andre Guedesc9ecc482012-03-15 16:52:08 -03001104 if (status) {
1105 hci_dev_lock(hdev);
1106 mgmt_stop_discovery_failed(hdev, status);
1107 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001108 return;
Andre Guedesc9ecc482012-03-15 16:52:08 -03001109 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001110
Andre Guedesd23264a2011-11-25 20:53:38 -03001111 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1112
Andre Guedesd0843292012-01-02 19:18:11 -03001113 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001114
Andre Guedesbc3dd332012-03-06 19:37:06 -03001115 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
1116 hdev->discovery.state == DISCOVERY_FINDING) {
Andre Guedes5e0452c2012-02-17 20:39:38 -03001117 mgmt_interleaved_discovery(hdev);
1118 } else {
1119 hci_dev_lock(hdev);
1120 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1121 hci_dev_unlock(hdev);
1122 }
1123
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001124 break;
1125
1126 default:
1127 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1128 break;
Andre Guedes35815082011-05-26 16:23:53 -03001129 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001130}
1131
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001132static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1133{
1134 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1135
1136 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1137
1138 if (rp->status)
1139 return;
1140
1141 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1142}
1143
1144static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1145{
1146 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1147
1148 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1149
1150 if (rp->status)
1151 return;
1152
1153 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1154}
1155
Andre Guedesf9b49302011-06-30 19:20:53 -03001156static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1157 struct sk_buff *skb)
1158{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001159 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001160 __u8 status = *((__u8 *) skb->data);
1161
1162 BT_DBG("%s status 0x%x", hdev->name, status);
1163
Johan Hedberg06199cf2012-02-22 16:37:11 +02001164 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001165 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001166 return;
1167
Johan Hedberg8f984df2012-02-28 01:07:22 +02001168 if (!status) {
1169 if (sent->le)
1170 hdev->host_features[0] |= LMP_HOST_LE;
1171 else
1172 hdev->host_features[0] &= ~LMP_HOST_LE;
1173 }
1174
1175 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
1176 !test_bit(HCI_INIT, &hdev->flags))
1177 mgmt_le_enable_complete(hdev, sent->le, status);
1178
1179 hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001180}
1181
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001182static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1183{
1184 BT_DBG("%s status 0x%x", hdev->name, status);
1185
1186 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001187 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001188 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001189 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001190 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001191 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001192 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001193 return;
1194 }
1195
Andre Guedes89352e72011-11-04 14:16:53 -03001196 set_bit(HCI_INQUIRY, &hdev->flags);
1197
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001198 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001199 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001200 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001201}
1202
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1204{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001205 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001208 BT_DBG("%s status 0x%x", hdev->name, status);
1209
1210 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 if (!cp)
1212 return;
1213
1214 hci_dev_lock(hdev);
1215
1216 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1217
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001218 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219
1220 if (status) {
1221 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001222 if (status != 0x0c || conn->attempt > 2) {
1223 conn->state = BT_CLOSED;
1224 hci_proto_connect_cfm(conn, status);
1225 hci_conn_del(conn);
1226 } else
1227 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 }
1229 } else {
1230 if (!conn) {
1231 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1232 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001233 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234 conn->link_mode |= HCI_LM_MASTER;
1235 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001236 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237 }
1238 }
1239
1240 hci_dev_unlock(hdev);
1241}
1242
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001243static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001245 struct hci_cp_add_sco *cp;
1246 struct hci_conn *acl, *sco;
1247 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001249 BT_DBG("%s status 0x%x", hdev->name, status);
1250
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001251 if (!status)
1252 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001254 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1255 if (!cp)
1256 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001258 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001259
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001260 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001261
1262 hci_dev_lock(hdev);
1263
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001264 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001265 if (acl) {
1266 sco = acl->link;
1267 if (sco) {
1268 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001269
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001270 hci_proto_connect_cfm(sco, status);
1271 hci_conn_del(sco);
1272 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001273 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001274
1275 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276}
1277
Marcel Holtmannf8558552008-07-14 20:13:49 +02001278static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1279{
1280 struct hci_cp_auth_requested *cp;
1281 struct hci_conn *conn;
1282
1283 BT_DBG("%s status 0x%x", hdev->name, status);
1284
1285 if (!status)
1286 return;
1287
1288 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1289 if (!cp)
1290 return;
1291
1292 hci_dev_lock(hdev);
1293
1294 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1295 if (conn) {
1296 if (conn->state == BT_CONFIG) {
1297 hci_proto_connect_cfm(conn, status);
1298 hci_conn_put(conn);
1299 }
1300 }
1301
1302 hci_dev_unlock(hdev);
1303}
1304
1305static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1306{
1307 struct hci_cp_set_conn_encrypt *cp;
1308 struct hci_conn *conn;
1309
1310 BT_DBG("%s status 0x%x", hdev->name, status);
1311
1312 if (!status)
1313 return;
1314
1315 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1316 if (!cp)
1317 return;
1318
1319 hci_dev_lock(hdev);
1320
1321 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1322 if (conn) {
1323 if (conn->state == BT_CONFIG) {
1324 hci_proto_connect_cfm(conn, status);
1325 hci_conn_put(conn);
1326 }
1327 }
1328
1329 hci_dev_unlock(hdev);
1330}
1331
Johan Hedberg127178d2010-11-18 22:22:29 +02001332static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001333 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001334{
Johan Hedberg392599b2010-11-18 22:22:28 +02001335 if (conn->state != BT_CONFIG || !conn->out)
1336 return 0;
1337
Johan Hedberg765c2a92011-01-19 12:06:52 +05301338 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001339 return 0;
1340
1341 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001342 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001343 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001344 conn->pending_sec_level != BT_SECURITY_HIGH &&
1345 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001346 return 0;
1347
Johan Hedberg392599b2010-11-18 22:22:28 +02001348 return 1;
1349}
1350
Gustavo F. Padovan00abfe42012-03-01 00:37:10 -03001351static inline int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001352 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001353{
1354 struct hci_cp_remote_name_req cp;
1355
1356 memset(&cp, 0, sizeof(cp));
1357
1358 bacpy(&cp.bdaddr, &e->data.bdaddr);
1359 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1360 cp.pscan_mode = e->data.pscan_mode;
1361 cp.clock_offset = e->data.clock_offset;
1362
1363 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1364}
1365
Johan Hedbergb644ba32012-01-17 21:48:47 +02001366static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001367{
1368 struct discovery_state *discov = &hdev->discovery;
1369 struct inquiry_entry *e;
1370
Johan Hedbergb644ba32012-01-17 21:48:47 +02001371 if (list_empty(&discov->resolve))
1372 return false;
1373
1374 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1375 if (hci_resolve_name(hdev, e) == 0) {
1376 e->name_state = NAME_PENDING;
1377 return true;
1378 }
1379
1380 return false;
1381}
1382
1383static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001384 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001385{
1386 struct discovery_state *discov = &hdev->discovery;
1387 struct inquiry_entry *e;
1388
1389 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001390 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1391 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001392
1393 if (discov->state == DISCOVERY_STOPPED)
1394 return;
1395
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001396 if (discov->state == DISCOVERY_STOPPING)
1397 goto discov_complete;
1398
1399 if (discov->state != DISCOVERY_RESOLVING)
1400 return;
1401
1402 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1403 if (e) {
1404 e->name_state = NAME_KNOWN;
1405 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001406 if (name)
1407 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001408 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001409 }
1410
Johan Hedbergb644ba32012-01-17 21:48:47 +02001411 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001412 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001413
1414discov_complete:
1415 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1416}
1417
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001418static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1419{
Johan Hedberg127178d2010-11-18 22:22:29 +02001420 struct hci_cp_remote_name_req *cp;
1421 struct hci_conn *conn;
1422
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001423 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001424
1425 /* If successful wait for the name req complete event before
1426 * checking for the need to do authentication */
1427 if (!status)
1428 return;
1429
1430 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1431 if (!cp)
1432 return;
1433
1434 hci_dev_lock(hdev);
1435
1436 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001437
1438 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1439 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1440
Johan Hedberg79c6c702011-04-28 11:28:55 -07001441 if (!conn)
1442 goto unlock;
1443
1444 if (!hci_outgoing_auth_needed(hdev, conn))
1445 goto unlock;
1446
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001447 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001448 struct hci_cp_auth_requested cp;
1449 cp.handle = __cpu_to_le16(conn->handle);
1450 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1451 }
1452
Johan Hedberg79c6c702011-04-28 11:28:55 -07001453unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001454 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001455}
1456
Marcel Holtmann769be972008-07-14 20:13:49 +02001457static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1458{
1459 struct hci_cp_read_remote_features *cp;
1460 struct hci_conn *conn;
1461
1462 BT_DBG("%s status 0x%x", hdev->name, status);
1463
1464 if (!status)
1465 return;
1466
1467 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1468 if (!cp)
1469 return;
1470
1471 hci_dev_lock(hdev);
1472
1473 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1474 if (conn) {
1475 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001476 hci_proto_connect_cfm(conn, status);
1477 hci_conn_put(conn);
1478 }
1479 }
1480
1481 hci_dev_unlock(hdev);
1482}
1483
1484static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1485{
1486 struct hci_cp_read_remote_ext_features *cp;
1487 struct hci_conn *conn;
1488
1489 BT_DBG("%s status 0x%x", hdev->name, status);
1490
1491 if (!status)
1492 return;
1493
1494 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1495 if (!cp)
1496 return;
1497
1498 hci_dev_lock(hdev);
1499
1500 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1501 if (conn) {
1502 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001503 hci_proto_connect_cfm(conn, status);
1504 hci_conn_put(conn);
1505 }
1506 }
1507
1508 hci_dev_unlock(hdev);
1509}
1510
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001511static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1512{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001513 struct hci_cp_setup_sync_conn *cp;
1514 struct hci_conn *acl, *sco;
1515 __u16 handle;
1516
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001517 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001518
1519 if (!status)
1520 return;
1521
1522 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1523 if (!cp)
1524 return;
1525
1526 handle = __le16_to_cpu(cp->handle);
1527
1528 BT_DBG("%s handle %d", hdev->name, handle);
1529
1530 hci_dev_lock(hdev);
1531
1532 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001533 if (acl) {
1534 sco = acl->link;
1535 if (sco) {
1536 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001537
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001538 hci_proto_connect_cfm(sco, status);
1539 hci_conn_del(sco);
1540 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001541 }
1542
1543 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001544}
1545
1546static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1547{
1548 struct hci_cp_sniff_mode *cp;
1549 struct hci_conn *conn;
1550
1551 BT_DBG("%s status 0x%x", hdev->name, status);
1552
1553 if (!status)
1554 return;
1555
1556 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1557 if (!cp)
1558 return;
1559
1560 hci_dev_lock(hdev);
1561
1562 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001563 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001564 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001565
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001566 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001567 hci_sco_setup(conn, status);
1568 }
1569
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001570 hci_dev_unlock(hdev);
1571}
1572
1573static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1574{
1575 struct hci_cp_exit_sniff_mode *cp;
1576 struct hci_conn *conn;
1577
1578 BT_DBG("%s status 0x%x", hdev->name, status);
1579
1580 if (!status)
1581 return;
1582
1583 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1584 if (!cp)
1585 return;
1586
1587 hci_dev_lock(hdev);
1588
1589 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001590 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001591 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001592
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001593 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001594 hci_sco_setup(conn, status);
1595 }
1596
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001597 hci_dev_unlock(hdev);
1598}
1599
Johan Hedberg88c3df12012-02-09 14:27:38 +02001600static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1601{
1602 struct hci_cp_disconnect *cp;
1603 struct hci_conn *conn;
1604
1605 if (!status)
1606 return;
1607
1608 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1609 if (!cp)
1610 return;
1611
1612 hci_dev_lock(hdev);
1613
1614 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1615 if (conn)
1616 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001617 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001618
1619 hci_dev_unlock(hdev);
1620}
1621
Ville Tervofcd89c02011-02-10 22:38:47 -03001622static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1623{
1624 struct hci_cp_le_create_conn *cp;
1625 struct hci_conn *conn;
1626
1627 BT_DBG("%s status 0x%x", hdev->name, status);
1628
1629 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1630 if (!cp)
1631 return;
1632
1633 hci_dev_lock(hdev);
1634
1635 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1636
1637 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1638 conn);
1639
1640 if (status) {
1641 if (conn && conn->state == BT_CONNECT) {
1642 conn->state = BT_CLOSED;
1643 hci_proto_connect_cfm(conn, status);
1644 hci_conn_del(conn);
1645 }
1646 } else {
1647 if (!conn) {
1648 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001649 if (conn) {
1650 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001651 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001652 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001653 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001654 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001655 }
1656 }
1657
1658 hci_dev_unlock(hdev);
1659}
1660
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001661static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1662{
1663 BT_DBG("%s status 0x%x", hdev->name, status);
1664}
1665
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001666static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1667{
1668 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001669 struct discovery_state *discov = &hdev->discovery;
1670 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001671
1672 BT_DBG("%s status %d", hdev->name, status);
1673
Johan Hedberg23bb5762010-12-21 23:01:27 +02001674 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001675
1676 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001677
1678 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1679 return;
1680
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001681 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001682 return;
1683
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001684 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001685
Andre Guedes343f9352012-02-17 20:39:37 -03001686 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001687 goto unlock;
1688
1689 if (list_empty(&discov->resolve)) {
1690 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1691 goto unlock;
1692 }
1693
1694 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1695 if (e && hci_resolve_name(hdev, e) == 0) {
1696 e->name_state = NAME_PENDING;
1697 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1698 } else {
1699 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1700 }
1701
1702unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001703 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001704}
1705
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1707{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001708 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001709 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 int num_rsp = *((__u8 *) skb->data);
1711
1712 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1713
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001714 if (!num_rsp)
1715 return;
1716
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001718
Johan Hedberge17acd42011-03-30 23:57:16 +03001719 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001720 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001721
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 bacpy(&data.bdaddr, &info->bdaddr);
1723 data.pscan_rep_mode = info->pscan_rep_mode;
1724 data.pscan_period_mode = info->pscan_period_mode;
1725 data.pscan_mode = info->pscan_mode;
1726 memcpy(data.dev_class, info->dev_class, 3);
1727 data.clock_offset = info->clock_offset;
1728 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001729 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001730
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001731 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001732 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001733 info->dev_class, 0, !name_known, ssp, NULL,
1734 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001736
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 hci_dev_unlock(hdev);
1738}
1739
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001740static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001742 struct hci_ev_conn_complete *ev = (void *) skb->data;
1743 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001745 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001746
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001748
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001749 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001750 if (!conn) {
1751 if (ev->link_type != SCO_LINK)
1752 goto unlock;
1753
1754 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1755 if (!conn)
1756 goto unlock;
1757
1758 conn->type = SCO_LINK;
1759 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001760
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001761 if (!ev->status) {
1762 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001763
1764 if (conn->type == ACL_LINK) {
1765 conn->state = BT_CONFIG;
1766 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001767 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001768 } else
1769 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001770
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001771 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001772 hci_conn_add_sysfs(conn);
1773
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001774 if (test_bit(HCI_AUTH, &hdev->flags))
1775 conn->link_mode |= HCI_LM_AUTH;
1776
1777 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1778 conn->link_mode |= HCI_LM_ENCRYPT;
1779
1780 /* Get remote features */
1781 if (conn->type == ACL_LINK) {
1782 struct hci_cp_read_remote_features cp;
1783 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001784 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001785 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001786 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001787
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001788 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001789 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001790 struct hci_cp_change_conn_ptype cp;
1791 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001792 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001793 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1794 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001795 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001796 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001797 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001798 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001799 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001800 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001801 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001802
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001803 if (conn->type == ACL_LINK)
1804 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001805
Marcel Holtmann769be972008-07-14 20:13:49 +02001806 if (ev->status) {
1807 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001808 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001809 } else if (ev->link_type != ACL_LINK)
1810 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001811
1812unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001814
1815 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816}
1817
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1819{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001820 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 int mask = hdev->link_mode;
1822
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001823 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1824 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825
1826 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1827
Szymon Janc138d22e2011-02-17 16:44:23 +01001828 if ((mask & HCI_LM_ACCEPT) &&
1829 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001831 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833
1834 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001835
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001836 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1837 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001838 memcpy(ie->data.dev_class, ev->dev_class, 3);
1839
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1841 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001842 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1843 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001844 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 hci_dev_unlock(hdev);
1846 return;
1847 }
1848 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001849
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 memcpy(conn->dev_class, ev->dev_class, 3);
1851 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001852
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 hci_dev_unlock(hdev);
1854
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001855 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1856 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001858 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001860 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1861 cp.role = 0x00; /* Become master */
1862 else
1863 cp.role = 0x01; /* Remain slave */
1864
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001865 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1866 &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001867 } else {
1868 struct hci_cp_accept_sync_conn_req cp;
1869
1870 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001871 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001872
1873 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1874 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1875 cp.max_latency = cpu_to_le16(0xffff);
1876 cp.content_format = cpu_to_le16(hdev->voice_setting);
1877 cp.retrans_effort = 0xff;
1878
1879 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001880 sizeof(cp), &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001881 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 } else {
1883 /* Connection rejected */
1884 struct hci_cp_reject_conn_req cp;
1885
1886 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001887 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001888 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889 }
1890}
1891
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1893{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001894 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001895 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896
1897 BT_DBG("%s status %d", hdev->name, ev->status);
1898
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 hci_dev_lock(hdev);
1900
Marcel Holtmann04837f62006-07-03 10:02:33 +02001901 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001902 if (!conn)
1903 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001904
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001905 if (ev->status == 0)
1906 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907
Johan Hedbergb644ba32012-01-17 21:48:47 +02001908 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1909 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001910 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001911 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1912 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001913 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001914 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001915 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001916 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001917
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001918 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301919 if (conn->type == ACL_LINK && conn->flush_key)
1920 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001921 hci_proto_disconn_cfm(conn, ev->reason);
1922 hci_conn_del(conn);
1923 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001924
1925unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926 hci_dev_unlock(hdev);
1927}
1928
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001929static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1930{
1931 struct hci_ev_auth_complete *ev = (void *) skb->data;
1932 struct hci_conn *conn;
1933
1934 BT_DBG("%s status %d", hdev->name, ev->status);
1935
1936 hci_dev_lock(hdev);
1937
1938 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001939 if (!conn)
1940 goto unlock;
1941
1942 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001943 if (!hci_conn_ssp_enabled(conn) &&
1944 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001945 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001946 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001947 conn->link_mode |= HCI_LM_AUTH;
1948 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001949 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001950 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001951 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001952 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001953 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001954
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001955 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1956 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001957
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001958 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001959 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001960 struct hci_cp_set_conn_encrypt cp;
1961 cp.handle = ev->handle;
1962 cp.encrypt = 0x01;
1963 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1964 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001965 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001966 conn->state = BT_CONNECTED;
1967 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001968 hci_conn_put(conn);
1969 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001970 } else {
1971 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001972
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001973 hci_conn_hold(conn);
1974 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1975 hci_conn_put(conn);
1976 }
1977
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001978 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001979 if (!ev->status) {
1980 struct hci_cp_set_conn_encrypt cp;
1981 cp.handle = ev->handle;
1982 cp.encrypt = 0x01;
1983 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1984 &cp);
1985 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001986 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001987 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001988 }
1989 }
1990
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001991unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001992 hci_dev_unlock(hdev);
1993}
1994
1995static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1996{
Johan Hedberg127178d2010-11-18 22:22:29 +02001997 struct hci_ev_remote_name *ev = (void *) skb->data;
1998 struct hci_conn *conn;
1999
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002000 BT_DBG("%s", hdev->name);
2001
2002 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002003
2004 hci_dev_lock(hdev);
2005
2006 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002007
2008 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2009 goto check_auth;
2010
2011 if (ev->status == 0)
2012 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002013 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002014 else
2015 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2016
2017check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002018 if (!conn)
2019 goto unlock;
2020
2021 if (!hci_outgoing_auth_needed(hdev, conn))
2022 goto unlock;
2023
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002024 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002025 struct hci_cp_auth_requested cp;
2026 cp.handle = __cpu_to_le16(conn->handle);
2027 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2028 }
2029
Johan Hedberg79c6c702011-04-28 11:28:55 -07002030unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002031 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002032}
2033
2034static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2035{
2036 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2037 struct hci_conn *conn;
2038
2039 BT_DBG("%s status %d", hdev->name, ev->status);
2040
2041 hci_dev_lock(hdev);
2042
2043 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2044 if (conn) {
2045 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002046 if (ev->encrypt) {
2047 /* Encryption implies authentication */
2048 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002049 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002050 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002051 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002052 conn->link_mode &= ~HCI_LM_ENCRYPT;
2053 }
2054
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002055 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002056
Marcel Holtmannf8558552008-07-14 20:13:49 +02002057 if (conn->state == BT_CONFIG) {
2058 if (!ev->status)
2059 conn->state = BT_CONNECTED;
2060
2061 hci_proto_connect_cfm(conn, ev->status);
2062 hci_conn_put(conn);
2063 } else
2064 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002065 }
2066
2067 hci_dev_unlock(hdev);
2068}
2069
2070static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2071{
2072 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2073 struct hci_conn *conn;
2074
2075 BT_DBG("%s status %d", hdev->name, ev->status);
2076
2077 hci_dev_lock(hdev);
2078
2079 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2080 if (conn) {
2081 if (!ev->status)
2082 conn->link_mode |= HCI_LM_SECURE;
2083
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002084 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002085
2086 hci_key_change_cfm(conn, ev->status);
2087 }
2088
2089 hci_dev_unlock(hdev);
2090}
2091
2092static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2093{
2094 struct hci_ev_remote_features *ev = (void *) skb->data;
2095 struct hci_conn *conn;
2096
2097 BT_DBG("%s status %d", hdev->name, ev->status);
2098
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002099 hci_dev_lock(hdev);
2100
2101 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002102 if (!conn)
2103 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002104
Johan Hedbergccd556f2010-11-10 17:11:51 +02002105 if (!ev->status)
2106 memcpy(conn->features, ev->features, 8);
2107
2108 if (conn->state != BT_CONFIG)
2109 goto unlock;
2110
2111 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2112 struct hci_cp_read_remote_ext_features cp;
2113 cp.handle = ev->handle;
2114 cp.page = 0x01;
2115 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002116 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002117 goto unlock;
2118 }
2119
Johan Hedberg127178d2010-11-18 22:22:29 +02002120 if (!ev->status) {
2121 struct hci_cp_remote_name_req cp;
2122 memset(&cp, 0, sizeof(cp));
2123 bacpy(&cp.bdaddr, &conn->dst);
2124 cp.pscan_rep_mode = 0x02;
2125 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002126 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2127 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002128 conn->dst_type, 0, NULL, 0,
2129 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002130
Johan Hedberg127178d2010-11-18 22:22:29 +02002131 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002132 conn->state = BT_CONNECTED;
2133 hci_proto_connect_cfm(conn, ev->status);
2134 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002135 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002136
Johan Hedbergccd556f2010-11-10 17:11:51 +02002137unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002138 hci_dev_unlock(hdev);
2139}
2140
2141static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2142{
2143 BT_DBG("%s", hdev->name);
2144}
2145
2146static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2147{
2148 BT_DBG("%s", hdev->name);
2149}
2150
2151static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2152{
2153 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2154 __u16 opcode;
2155
2156 skb_pull(skb, sizeof(*ev));
2157
2158 opcode = __le16_to_cpu(ev->opcode);
2159
2160 switch (opcode) {
2161 case HCI_OP_INQUIRY_CANCEL:
2162 hci_cc_inquiry_cancel(hdev, skb);
2163 break;
2164
Andre Guedes4d934832012-03-21 00:03:35 -03002165 case HCI_OP_PERIODIC_INQ:
2166 hci_cc_periodic_inq(hdev, skb);
2167 break;
2168
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002169 case HCI_OP_EXIT_PERIODIC_INQ:
2170 hci_cc_exit_periodic_inq(hdev, skb);
2171 break;
2172
2173 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2174 hci_cc_remote_name_req_cancel(hdev, skb);
2175 break;
2176
2177 case HCI_OP_ROLE_DISCOVERY:
2178 hci_cc_role_discovery(hdev, skb);
2179 break;
2180
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002181 case HCI_OP_READ_LINK_POLICY:
2182 hci_cc_read_link_policy(hdev, skb);
2183 break;
2184
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002185 case HCI_OP_WRITE_LINK_POLICY:
2186 hci_cc_write_link_policy(hdev, skb);
2187 break;
2188
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002189 case HCI_OP_READ_DEF_LINK_POLICY:
2190 hci_cc_read_def_link_policy(hdev, skb);
2191 break;
2192
2193 case HCI_OP_WRITE_DEF_LINK_POLICY:
2194 hci_cc_write_def_link_policy(hdev, skb);
2195 break;
2196
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002197 case HCI_OP_RESET:
2198 hci_cc_reset(hdev, skb);
2199 break;
2200
2201 case HCI_OP_WRITE_LOCAL_NAME:
2202 hci_cc_write_local_name(hdev, skb);
2203 break;
2204
2205 case HCI_OP_READ_LOCAL_NAME:
2206 hci_cc_read_local_name(hdev, skb);
2207 break;
2208
2209 case HCI_OP_WRITE_AUTH_ENABLE:
2210 hci_cc_write_auth_enable(hdev, skb);
2211 break;
2212
2213 case HCI_OP_WRITE_ENCRYPT_MODE:
2214 hci_cc_write_encrypt_mode(hdev, skb);
2215 break;
2216
2217 case HCI_OP_WRITE_SCAN_ENABLE:
2218 hci_cc_write_scan_enable(hdev, skb);
2219 break;
2220
2221 case HCI_OP_READ_CLASS_OF_DEV:
2222 hci_cc_read_class_of_dev(hdev, skb);
2223 break;
2224
2225 case HCI_OP_WRITE_CLASS_OF_DEV:
2226 hci_cc_write_class_of_dev(hdev, skb);
2227 break;
2228
2229 case HCI_OP_READ_VOICE_SETTING:
2230 hci_cc_read_voice_setting(hdev, skb);
2231 break;
2232
2233 case HCI_OP_WRITE_VOICE_SETTING:
2234 hci_cc_write_voice_setting(hdev, skb);
2235 break;
2236
2237 case HCI_OP_HOST_BUFFER_SIZE:
2238 hci_cc_host_buffer_size(hdev, skb);
2239 break;
2240
Marcel Holtmann333140b2008-07-14 20:13:48 +02002241 case HCI_OP_WRITE_SSP_MODE:
2242 hci_cc_write_ssp_mode(hdev, skb);
2243 break;
2244
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002245 case HCI_OP_READ_LOCAL_VERSION:
2246 hci_cc_read_local_version(hdev, skb);
2247 break;
2248
2249 case HCI_OP_READ_LOCAL_COMMANDS:
2250 hci_cc_read_local_commands(hdev, skb);
2251 break;
2252
2253 case HCI_OP_READ_LOCAL_FEATURES:
2254 hci_cc_read_local_features(hdev, skb);
2255 break;
2256
Andre Guedes971e3a42011-06-30 19:20:52 -03002257 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2258 hci_cc_read_local_ext_features(hdev, skb);
2259 break;
2260
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002261 case HCI_OP_READ_BUFFER_SIZE:
2262 hci_cc_read_buffer_size(hdev, skb);
2263 break;
2264
2265 case HCI_OP_READ_BD_ADDR:
2266 hci_cc_read_bd_addr(hdev, skb);
2267 break;
2268
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002269 case HCI_OP_READ_DATA_BLOCK_SIZE:
2270 hci_cc_read_data_block_size(hdev, skb);
2271 break;
2272
Johan Hedberg23bb5762010-12-21 23:01:27 +02002273 case HCI_OP_WRITE_CA_TIMEOUT:
2274 hci_cc_write_ca_timeout(hdev, skb);
2275 break;
2276
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002277 case HCI_OP_READ_FLOW_CONTROL_MODE:
2278 hci_cc_read_flow_control_mode(hdev, skb);
2279 break;
2280
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002281 case HCI_OP_READ_LOCAL_AMP_INFO:
2282 hci_cc_read_local_amp_info(hdev, skb);
2283 break;
2284
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002285 case HCI_OP_DELETE_STORED_LINK_KEY:
2286 hci_cc_delete_stored_link_key(hdev, skb);
2287 break;
2288
Johan Hedbergd5859e22011-01-25 01:19:58 +02002289 case HCI_OP_SET_EVENT_MASK:
2290 hci_cc_set_event_mask(hdev, skb);
2291 break;
2292
2293 case HCI_OP_WRITE_INQUIRY_MODE:
2294 hci_cc_write_inquiry_mode(hdev, skb);
2295 break;
2296
2297 case HCI_OP_READ_INQ_RSP_TX_POWER:
2298 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2299 break;
2300
2301 case HCI_OP_SET_EVENT_FLT:
2302 hci_cc_set_event_flt(hdev, skb);
2303 break;
2304
Johan Hedberg980e1a52011-01-22 06:10:07 +02002305 case HCI_OP_PIN_CODE_REPLY:
2306 hci_cc_pin_code_reply(hdev, skb);
2307 break;
2308
2309 case HCI_OP_PIN_CODE_NEG_REPLY:
2310 hci_cc_pin_code_neg_reply(hdev, skb);
2311 break;
2312
Szymon Jancc35938b2011-03-22 13:12:21 +01002313 case HCI_OP_READ_LOCAL_OOB_DATA:
2314 hci_cc_read_local_oob_data_reply(hdev, skb);
2315 break;
2316
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002317 case HCI_OP_LE_READ_BUFFER_SIZE:
2318 hci_cc_le_read_buffer_size(hdev, skb);
2319 break;
2320
Johan Hedberga5c29682011-02-19 12:05:57 -03002321 case HCI_OP_USER_CONFIRM_REPLY:
2322 hci_cc_user_confirm_reply(hdev, skb);
2323 break;
2324
2325 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2326 hci_cc_user_confirm_neg_reply(hdev, skb);
2327 break;
2328
Brian Gix1143d452011-11-23 08:28:34 -08002329 case HCI_OP_USER_PASSKEY_REPLY:
2330 hci_cc_user_passkey_reply(hdev, skb);
2331 break;
2332
2333 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2334 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002335 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002336
2337 case HCI_OP_LE_SET_SCAN_PARAM:
2338 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002339 break;
2340
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002341 case HCI_OP_LE_SET_SCAN_ENABLE:
2342 hci_cc_le_set_scan_enable(hdev, skb);
2343 break;
2344
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002345 case HCI_OP_LE_LTK_REPLY:
2346 hci_cc_le_ltk_reply(hdev, skb);
2347 break;
2348
2349 case HCI_OP_LE_LTK_NEG_REPLY:
2350 hci_cc_le_ltk_neg_reply(hdev, skb);
2351 break;
2352
Andre Guedesf9b49302011-06-30 19:20:53 -03002353 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2354 hci_cc_write_le_host_supported(hdev, skb);
2355 break;
2356
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002357 default:
2358 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2359 break;
2360 }
2361
Ville Tervo6bd32322011-02-16 16:32:41 +02002362 if (ev->opcode != HCI_OP_NOP)
2363 del_timer(&hdev->cmd_timer);
2364
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002365 if (ev->ncmd) {
2366 atomic_set(&hdev->cmd_cnt, 1);
2367 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002368 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002369 }
2370}
2371
2372static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2373{
2374 struct hci_ev_cmd_status *ev = (void *) skb->data;
2375 __u16 opcode;
2376
2377 skb_pull(skb, sizeof(*ev));
2378
2379 opcode = __le16_to_cpu(ev->opcode);
2380
2381 switch (opcode) {
2382 case HCI_OP_INQUIRY:
2383 hci_cs_inquiry(hdev, ev->status);
2384 break;
2385
2386 case HCI_OP_CREATE_CONN:
2387 hci_cs_create_conn(hdev, ev->status);
2388 break;
2389
2390 case HCI_OP_ADD_SCO:
2391 hci_cs_add_sco(hdev, ev->status);
2392 break;
2393
Marcel Holtmannf8558552008-07-14 20:13:49 +02002394 case HCI_OP_AUTH_REQUESTED:
2395 hci_cs_auth_requested(hdev, ev->status);
2396 break;
2397
2398 case HCI_OP_SET_CONN_ENCRYPT:
2399 hci_cs_set_conn_encrypt(hdev, ev->status);
2400 break;
2401
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002402 case HCI_OP_REMOTE_NAME_REQ:
2403 hci_cs_remote_name_req(hdev, ev->status);
2404 break;
2405
Marcel Holtmann769be972008-07-14 20:13:49 +02002406 case HCI_OP_READ_REMOTE_FEATURES:
2407 hci_cs_read_remote_features(hdev, ev->status);
2408 break;
2409
2410 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2411 hci_cs_read_remote_ext_features(hdev, ev->status);
2412 break;
2413
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002414 case HCI_OP_SETUP_SYNC_CONN:
2415 hci_cs_setup_sync_conn(hdev, ev->status);
2416 break;
2417
2418 case HCI_OP_SNIFF_MODE:
2419 hci_cs_sniff_mode(hdev, ev->status);
2420 break;
2421
2422 case HCI_OP_EXIT_SNIFF_MODE:
2423 hci_cs_exit_sniff_mode(hdev, ev->status);
2424 break;
2425
Johan Hedberg8962ee72011-01-20 12:40:27 +02002426 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002427 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002428 break;
2429
Ville Tervofcd89c02011-02-10 22:38:47 -03002430 case HCI_OP_LE_CREATE_CONN:
2431 hci_cs_le_create_conn(hdev, ev->status);
2432 break;
2433
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002434 case HCI_OP_LE_START_ENC:
2435 hci_cs_le_start_enc(hdev, ev->status);
2436 break;
2437
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002438 default:
2439 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2440 break;
2441 }
2442
Ville Tervo6bd32322011-02-16 16:32:41 +02002443 if (ev->opcode != HCI_OP_NOP)
2444 del_timer(&hdev->cmd_timer);
2445
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002446 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002447 atomic_set(&hdev->cmd_cnt, 1);
2448 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002449 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002450 }
2451}
2452
2453static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2454{
2455 struct hci_ev_role_change *ev = (void *) skb->data;
2456 struct hci_conn *conn;
2457
2458 BT_DBG("%s status %d", hdev->name, ev->status);
2459
2460 hci_dev_lock(hdev);
2461
2462 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2463 if (conn) {
2464 if (!ev->status) {
2465 if (ev->role)
2466 conn->link_mode &= ~HCI_LM_MASTER;
2467 else
2468 conn->link_mode |= HCI_LM_MASTER;
2469 }
2470
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002471 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002472
2473 hci_role_switch_cfm(conn, ev->status, ev->role);
2474 }
2475
2476 hci_dev_unlock(hdev);
2477}
2478
Linus Torvalds1da177e2005-04-16 15:20:36 -07002479static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2480{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002481 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482 int i;
2483
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002484 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2485 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2486 return;
2487 }
2488
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002489 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2490 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002491 BT_DBG("%s bad parameters", hdev->name);
2492 return;
2493 }
2494
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002495 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2496
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002497 for (i = 0; i < ev->num_hndl; i++) {
2498 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 struct hci_conn *conn;
2500 __u16 handle, count;
2501
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002502 handle = __le16_to_cpu(info->handle);
2503 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504
2505 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002506 if (!conn)
2507 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002509 conn->sent -= count;
2510
2511 switch (conn->type) {
2512 case ACL_LINK:
2513 hdev->acl_cnt += count;
2514 if (hdev->acl_cnt > hdev->acl_pkts)
2515 hdev->acl_cnt = hdev->acl_pkts;
2516 break;
2517
2518 case LE_LINK:
2519 if (hdev->le_pkts) {
2520 hdev->le_cnt += count;
2521 if (hdev->le_cnt > hdev->le_pkts)
2522 hdev->le_cnt = hdev->le_pkts;
2523 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002524 hdev->acl_cnt += count;
2525 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526 hdev->acl_cnt = hdev->acl_pkts;
2527 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002528 break;
2529
2530 case SCO_LINK:
2531 hdev->sco_cnt += count;
2532 if (hdev->sco_cnt > hdev->sco_pkts)
2533 hdev->sco_cnt = hdev->sco_pkts;
2534 break;
2535
2536 default:
2537 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2538 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539 }
2540 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002541
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002542 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543}
2544
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002545static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002546 struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002547{
2548 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2549 int i;
2550
2551 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2552 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2553 return;
2554 }
2555
2556 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2557 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2558 BT_DBG("%s bad parameters", hdev->name);
2559 return;
2560 }
2561
2562 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2563 ev->num_hndl);
2564
2565 for (i = 0; i < ev->num_hndl; i++) {
2566 struct hci_comp_blocks_info *info = &ev->handles[i];
2567 struct hci_conn *conn;
2568 __u16 handle, block_count;
2569
2570 handle = __le16_to_cpu(info->handle);
2571 block_count = __le16_to_cpu(info->blocks);
2572
2573 conn = hci_conn_hash_lookup_handle(hdev, handle);
2574 if (!conn)
2575 continue;
2576
2577 conn->sent -= block_count;
2578
2579 switch (conn->type) {
2580 case ACL_LINK:
2581 hdev->block_cnt += block_count;
2582 if (hdev->block_cnt > hdev->num_blocks)
2583 hdev->block_cnt = hdev->num_blocks;
2584 break;
2585
2586 default:
2587 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2588 break;
2589 }
2590 }
2591
2592 queue_work(hdev->workqueue, &hdev->tx_work);
2593}
2594
Marcel Holtmann04837f62006-07-03 10:02:33 +02002595static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002597 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002598 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002599
2600 BT_DBG("%s status %d", hdev->name, ev->status);
2601
2602 hci_dev_lock(hdev);
2603
Marcel Holtmann04837f62006-07-03 10:02:33 +02002604 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2605 if (conn) {
2606 conn->mode = ev->mode;
2607 conn->interval = __le16_to_cpu(ev->interval);
2608
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002609 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002610 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002611 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002612 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002613 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002614 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002615
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002616 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002617 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002618 }
2619
2620 hci_dev_unlock(hdev);
2621}
2622
Linus Torvalds1da177e2005-04-16 15:20:36 -07002623static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2624{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002625 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2626 struct hci_conn *conn;
2627
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002628 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002629
2630 hci_dev_lock(hdev);
2631
2632 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002633 if (!conn)
2634 goto unlock;
2635
2636 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002637 hci_conn_hold(conn);
2638 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2639 hci_conn_put(conn);
2640 }
2641
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002642 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002643 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2644 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002645 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002646 u8 secure;
2647
2648 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2649 secure = 1;
2650 else
2651 secure = 0;
2652
Johan Hedberg744cf192011-11-08 20:40:14 +02002653 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002654 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002655
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002656unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002657 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658}
2659
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2661{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002662 struct hci_ev_link_key_req *ev = (void *) skb->data;
2663 struct hci_cp_link_key_reply cp;
2664 struct hci_conn *conn;
2665 struct link_key *key;
2666
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002667 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002668
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002669 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002670 return;
2671
2672 hci_dev_lock(hdev);
2673
2674 key = hci_find_link_key(hdev, &ev->bdaddr);
2675 if (!key) {
2676 BT_DBG("%s link key not found for %s", hdev->name,
2677 batostr(&ev->bdaddr));
2678 goto not_found;
2679 }
2680
2681 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2682 batostr(&ev->bdaddr));
2683
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002684 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002685 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002686 BT_DBG("%s ignoring debug key", hdev->name);
2687 goto not_found;
2688 }
2689
2690 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002691 if (conn) {
2692 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2693 conn->auth_type != 0xff &&
2694 (conn->auth_type & 0x01)) {
2695 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2696 goto not_found;
2697 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002698
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002699 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2700 conn->pending_sec_level == BT_SECURITY_HIGH) {
2701 BT_DBG("%s ignoring key unauthenticated for high \
2702 security", hdev->name);
2703 goto not_found;
2704 }
2705
2706 conn->key_type = key->type;
2707 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002708 }
2709
2710 bacpy(&cp.bdaddr, &ev->bdaddr);
2711 memcpy(cp.link_key, key->val, 16);
2712
2713 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2714
2715 hci_dev_unlock(hdev);
2716
2717 return;
2718
2719not_found:
2720 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2721 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002722}
2723
Linus Torvalds1da177e2005-04-16 15:20:36 -07002724static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2725{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002726 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2727 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002728 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002729
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002730 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002731
2732 hci_dev_lock(hdev);
2733
2734 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2735 if (conn) {
2736 hci_conn_hold(conn);
2737 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002738 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002739
2740 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2741 conn->key_type = ev->key_type;
2742
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002743 hci_conn_put(conn);
2744 }
2745
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002746 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002747 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002748 ev->key_type, pin_len);
2749
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002750 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751}
2752
Marcel Holtmann04837f62006-07-03 10:02:33 +02002753static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2754{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002755 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002756 struct hci_conn *conn;
2757
2758 BT_DBG("%s status %d", hdev->name, ev->status);
2759
2760 hci_dev_lock(hdev);
2761
2762 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002763 if (conn && !ev->status) {
2764 struct inquiry_entry *ie;
2765
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002766 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2767 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768 ie->data.clock_offset = ev->clock_offset;
2769 ie->timestamp = jiffies;
2770 }
2771 }
2772
2773 hci_dev_unlock(hdev);
2774}
2775
Marcel Holtmanna8746412008-07-14 20:13:46 +02002776static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2777{
2778 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2779 struct hci_conn *conn;
2780
2781 BT_DBG("%s status %d", hdev->name, ev->status);
2782
2783 hci_dev_lock(hdev);
2784
2785 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2786 if (conn && !ev->status)
2787 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2788
2789 hci_dev_unlock(hdev);
2790}
2791
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002792static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2793{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002794 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002795 struct inquiry_entry *ie;
2796
2797 BT_DBG("%s", hdev->name);
2798
2799 hci_dev_lock(hdev);
2800
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002801 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2802 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002803 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2804 ie->timestamp = jiffies;
2805 }
2806
2807 hci_dev_unlock(hdev);
2808}
2809
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002810static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2811{
2812 struct inquiry_data data;
2813 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002814 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002815
2816 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2817
2818 if (!num_rsp)
2819 return;
2820
2821 hci_dev_lock(hdev);
2822
2823 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002824 struct inquiry_info_with_rssi_and_pscan_mode *info;
2825 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002826
Johan Hedberge17acd42011-03-30 23:57:16 +03002827 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002828 bacpy(&data.bdaddr, &info->bdaddr);
2829 data.pscan_rep_mode = info->pscan_rep_mode;
2830 data.pscan_period_mode = info->pscan_period_mode;
2831 data.pscan_mode = info->pscan_mode;
2832 memcpy(data.dev_class, info->dev_class, 3);
2833 data.clock_offset = info->clock_offset;
2834 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002835 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002836
2837 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002838 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002839 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002840 info->dev_class, info->rssi,
2841 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002842 }
2843 } else {
2844 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2845
Johan Hedberge17acd42011-03-30 23:57:16 +03002846 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002847 bacpy(&data.bdaddr, &info->bdaddr);
2848 data.pscan_rep_mode = info->pscan_rep_mode;
2849 data.pscan_period_mode = info->pscan_period_mode;
2850 data.pscan_mode = 0x00;
2851 memcpy(data.dev_class, info->dev_class, 3);
2852 data.clock_offset = info->clock_offset;
2853 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002854 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002855 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002856 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002857 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002858 info->dev_class, info->rssi,
2859 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002860 }
2861 }
2862
2863 hci_dev_unlock(hdev);
2864}
2865
2866static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2867{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002868 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2869 struct hci_conn *conn;
2870
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002871 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002872
Marcel Holtmann41a96212008-07-14 20:13:48 +02002873 hci_dev_lock(hdev);
2874
2875 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002876 if (!conn)
2877 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002878
Johan Hedbergccd556f2010-11-10 17:11:51 +02002879 if (!ev->status && ev->page == 0x01) {
2880 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002881
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002882 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2883 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002884 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002885
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002886 if (ev->features[0] & LMP_HOST_SSP)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002887 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002888 }
2889
Johan Hedbergccd556f2010-11-10 17:11:51 +02002890 if (conn->state != BT_CONFIG)
2891 goto unlock;
2892
Johan Hedberg127178d2010-11-18 22:22:29 +02002893 if (!ev->status) {
2894 struct hci_cp_remote_name_req cp;
2895 memset(&cp, 0, sizeof(cp));
2896 bacpy(&cp.bdaddr, &conn->dst);
2897 cp.pscan_rep_mode = 0x02;
2898 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002899 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2900 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002901 conn->dst_type, 0, NULL, 0,
2902 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002903
Johan Hedberg127178d2010-11-18 22:22:29 +02002904 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002905 conn->state = BT_CONNECTED;
2906 hci_proto_connect_cfm(conn, ev->status);
2907 hci_conn_put(conn);
2908 }
2909
2910unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002911 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002912}
2913
2914static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2915{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002916 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2917 struct hci_conn *conn;
2918
2919 BT_DBG("%s status %d", hdev->name, ev->status);
2920
2921 hci_dev_lock(hdev);
2922
2923 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002924 if (!conn) {
2925 if (ev->link_type == ESCO_LINK)
2926 goto unlock;
2927
2928 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2929 if (!conn)
2930 goto unlock;
2931
2932 conn->type = SCO_LINK;
2933 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002934
Marcel Holtmann732547f2009-04-19 19:14:14 +02002935 switch (ev->status) {
2936 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002937 conn->handle = __le16_to_cpu(ev->handle);
2938 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002939
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002940 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002941 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002942 break;
2943
Stephen Coe705e5712010-02-16 11:29:44 -05002944 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002945 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002946 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002947 case 0x1f: /* Unspecified error */
2948 if (conn->out && conn->attempt < 2) {
2949 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2950 (hdev->esco_type & EDR_ESCO_MASK);
2951 hci_setup_sync(conn, conn->link->handle);
2952 goto unlock;
2953 }
2954 /* fall through */
2955
2956 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002957 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002958 break;
2959 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002960
2961 hci_proto_connect_cfm(conn, ev->status);
2962 if (ev->status)
2963 hci_conn_del(conn);
2964
2965unlock:
2966 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002967}
2968
2969static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2970{
2971 BT_DBG("%s", hdev->name);
2972}
2973
Marcel Holtmann04837f62006-07-03 10:02:33 +02002974static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2975{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002976 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002977
2978 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002979}
2980
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002981static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2982{
2983 struct inquiry_data data;
2984 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2985 int num_rsp = *((__u8 *) skb->data);
2986
2987 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2988
2989 if (!num_rsp)
2990 return;
2991
2992 hci_dev_lock(hdev);
2993
Johan Hedberge17acd42011-03-30 23:57:16 +03002994 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002995 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002996
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002997 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002998 data.pscan_rep_mode = info->pscan_rep_mode;
2999 data.pscan_period_mode = info->pscan_period_mode;
3000 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003001 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003002 data.clock_offset = info->clock_offset;
3003 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003004 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003005
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003006 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003007 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003008 sizeof(info->data),
3009 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003010 else
3011 name_known = true;
3012
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003013 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003014 &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003015 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003016 info->dev_class, info->rssi, !name_known,
3017 ssp, info->data, sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003018 }
3019
3020 hci_dev_unlock(hdev);
3021}
3022
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003023static inline u8 hci_get_auth_req(struct hci_conn *conn)
3024{
3025 /* If remote requests dedicated bonding follow that lead */
3026 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3027 /* If both remote and local IO capabilities allow MITM
3028 * protection then require it, otherwise don't */
3029 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3030 return 0x02;
3031 else
3032 return 0x03;
3033 }
3034
3035 /* If remote requests no-bonding follow that lead */
3036 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003037 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003038
3039 return conn->auth_type;
3040}
3041
Marcel Holtmann04936842008-07-14 20:13:48 +02003042static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3043{
3044 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3045 struct hci_conn *conn;
3046
3047 BT_DBG("%s", hdev->name);
3048
3049 hci_dev_lock(hdev);
3050
3051 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003052 if (!conn)
3053 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003054
Johan Hedberg03b555e2011-01-04 15:40:05 +02003055 hci_conn_hold(conn);
3056
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003057 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003058 goto unlock;
3059
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003060 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003061 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003062 struct hci_cp_io_capability_reply cp;
3063
3064 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303065 /* Change the IO capability from KeyboardDisplay
3066 * to DisplayYesNo as it is not supported by BT spec. */
3067 cp.capability = (conn->io_capability == 0x04) ?
3068 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003069 conn->auth_type = hci_get_auth_req(conn);
3070 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003071
Johan Hedberg58a681e2012-01-16 06:47:28 +02003072 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003073 hci_find_remote_oob_data(hdev, &conn->dst))
3074 cp.oob_data = 0x01;
3075 else
3076 cp.oob_data = 0x00;
3077
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003078 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3079 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003080 } else {
3081 struct hci_cp_io_capability_neg_reply cp;
3082
3083 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003084 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003085
3086 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3087 sizeof(cp), &cp);
3088 }
3089
3090unlock:
3091 hci_dev_unlock(hdev);
3092}
3093
3094static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3095{
3096 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3097 struct hci_conn *conn;
3098
3099 BT_DBG("%s", hdev->name);
3100
3101 hci_dev_lock(hdev);
3102
3103 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3104 if (!conn)
3105 goto unlock;
3106
Johan Hedberg03b555e2011-01-04 15:40:05 +02003107 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003108 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003109 if (ev->oob_data)
3110 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003111
3112unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003113 hci_dev_unlock(hdev);
3114}
3115
Johan Hedberga5c29682011-02-19 12:05:57 -03003116static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3117 struct sk_buff *skb)
3118{
3119 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003120 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003121 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003122
3123 BT_DBG("%s", hdev->name);
3124
3125 hci_dev_lock(hdev);
3126
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003127 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003128 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003129
Johan Hedberg7a828902011-04-28 11:28:53 -07003130 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3131 if (!conn)
3132 goto unlock;
3133
3134 loc_mitm = (conn->auth_type & 0x01);
3135 rem_mitm = (conn->remote_auth & 0x01);
3136
3137 /* If we require MITM but the remote device can't provide that
3138 * (it has NoInputNoOutput) then reject the confirmation
3139 * request. The only exception is when we're dedicated bonding
3140 * initiators (connect_cfm_cb set) since then we always have the MITM
3141 * bit set. */
3142 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3143 BT_DBG("Rejecting request: remote device can't provide MITM");
3144 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3145 sizeof(ev->bdaddr), &ev->bdaddr);
3146 goto unlock;
3147 }
3148
3149 /* If no side requires MITM protection; auto-accept */
3150 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3151 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003152
3153 /* If we're not the initiators request authorization to
3154 * proceed from user space (mgmt_user_confirm with
3155 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003156 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003157 BT_DBG("Confirming auto-accept as acceptor");
3158 confirm_hint = 1;
3159 goto confirm;
3160 }
3161
Johan Hedberg9f616562011-04-28 11:28:54 -07003162 BT_DBG("Auto-accept of user confirmation with %ums delay",
3163 hdev->auto_accept_delay);
3164
3165 if (hdev->auto_accept_delay > 0) {
3166 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3167 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3168 goto unlock;
3169 }
3170
Johan Hedberg7a828902011-04-28 11:28:53 -07003171 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3172 sizeof(ev->bdaddr), &ev->bdaddr);
3173 goto unlock;
3174 }
3175
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003176confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003177 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003178 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003179
3180unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003181 hci_dev_unlock(hdev);
3182}
3183
Brian Gix1143d452011-11-23 08:28:34 -08003184static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3185 struct sk_buff *skb)
3186{
3187 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3188
3189 BT_DBG("%s", hdev->name);
3190
3191 hci_dev_lock(hdev);
3192
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003193 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003194 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003195
3196 hci_dev_unlock(hdev);
3197}
3198
Marcel Holtmann04936842008-07-14 20:13:48 +02003199static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3200{
3201 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3202 struct hci_conn *conn;
3203
3204 BT_DBG("%s", hdev->name);
3205
3206 hci_dev_lock(hdev);
3207
3208 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003209 if (!conn)
3210 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003211
Johan Hedberg2a611692011-02-19 12:06:00 -03003212 /* To avoid duplicate auth_failed events to user space we check
3213 * the HCI_CONN_AUTH_PEND flag which will be set if we
3214 * initiated the authentication. A traditional auth_complete
3215 * event gets always produced as initiator and is also mapped to
3216 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003217 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003218 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003219 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003220
3221 hci_conn_put(conn);
3222
3223unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003224 hci_dev_unlock(hdev);
3225}
3226
Marcel Holtmann41a96212008-07-14 20:13:48 +02003227static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3228{
3229 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3230 struct inquiry_entry *ie;
3231
3232 BT_DBG("%s", hdev->name);
3233
3234 hci_dev_lock(hdev);
3235
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003236 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3237 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003238 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003239
3240 hci_dev_unlock(hdev);
3241}
3242
Szymon Janc2763eda2011-03-22 13:12:22 +01003243static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003244 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003245{
3246 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3247 struct oob_data *data;
3248
3249 BT_DBG("%s", hdev->name);
3250
3251 hci_dev_lock(hdev);
3252
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003253 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003254 goto unlock;
3255
Szymon Janc2763eda2011-03-22 13:12:22 +01003256 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3257 if (data) {
3258 struct hci_cp_remote_oob_data_reply cp;
3259
3260 bacpy(&cp.bdaddr, &ev->bdaddr);
3261 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3262 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3263
3264 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3265 &cp);
3266 } else {
3267 struct hci_cp_remote_oob_data_neg_reply cp;
3268
3269 bacpy(&cp.bdaddr, &ev->bdaddr);
3270 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3271 &cp);
3272 }
3273
Szymon Jance1ba1f12011-04-06 13:01:59 +02003274unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003275 hci_dev_unlock(hdev);
3276}
3277
Ville Tervofcd89c02011-02-10 22:38:47 -03003278static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3279{
3280 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3281 struct hci_conn *conn;
3282
3283 BT_DBG("%s status %d", hdev->name, ev->status);
3284
3285 hci_dev_lock(hdev);
3286
3287 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003288 if (!conn) {
3289 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3290 if (!conn) {
3291 BT_ERR("No memory for new connection");
3292 hci_dev_unlock(hdev);
3293 return;
3294 }
Andre Guedes29b79882011-05-31 14:20:54 -03003295
3296 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003297 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003298
3299 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003300 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3301 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003302 hci_proto_connect_cfm(conn, ev->status);
3303 conn->state = BT_CLOSED;
3304 hci_conn_del(conn);
3305 goto unlock;
3306 }
3307
Johan Hedbergb644ba32012-01-17 21:48:47 +02003308 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3309 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003310 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003311
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003312 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003313 conn->handle = __le16_to_cpu(ev->handle);
3314 conn->state = BT_CONNECTED;
3315
3316 hci_conn_hold_device(conn);
3317 hci_conn_add_sysfs(conn);
3318
3319 hci_proto_connect_cfm(conn, ev->status);
3320
3321unlock:
3322 hci_dev_unlock(hdev);
3323}
3324
Andre Guedes9aa04c92011-05-26 16:23:51 -03003325static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3326 struct sk_buff *skb)
3327{
Andre Guedese95beb42011-09-26 20:48:35 -03003328 u8 num_reports = skb->data[0];
3329 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003330 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003331
3332 hci_dev_lock(hdev);
3333
Andre Guedese95beb42011-09-26 20:48:35 -03003334 while (num_reports--) {
3335 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003336
Andre Guedes9aa04c92011-05-26 16:23:51 -03003337 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003338
Andre Guedes3c9e9192012-01-10 18:20:50 -03003339 rssi = ev->data[ev->length];
3340 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003341 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003342
Andre Guedese95beb42011-09-26 20:48:35 -03003343 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003344 }
3345
3346 hci_dev_unlock(hdev);
3347}
3348
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003349static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3350 struct sk_buff *skb)
3351{
3352 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3353 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003354 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003355 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003356 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003357
Andrei Emeltchenkoe4666882012-03-09 11:59:15 +02003358 BT_DBG("%s handle %d", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003359
3360 hci_dev_lock(hdev);
3361
3362 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003363 if (conn == NULL)
3364 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003365
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003366 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3367 if (ltk == NULL)
3368 goto not_found;
3369
3370 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003371 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003372
3373 if (ltk->authenticated)
3374 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003375
3376 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3377
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003378 if (ltk->type & HCI_SMP_STK) {
3379 list_del(&ltk->list);
3380 kfree(ltk);
3381 }
3382
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003383 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003384
3385 return;
3386
3387not_found:
3388 neg.handle = ev->handle;
3389 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3390 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003391}
3392
Ville Tervofcd89c02011-02-10 22:38:47 -03003393static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3394{
3395 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3396
3397 skb_pull(skb, sizeof(*le_ev));
3398
3399 switch (le_ev->subevent) {
3400 case HCI_EV_LE_CONN_COMPLETE:
3401 hci_le_conn_complete_evt(hdev, skb);
3402 break;
3403
Andre Guedes9aa04c92011-05-26 16:23:51 -03003404 case HCI_EV_LE_ADVERTISING_REPORT:
3405 hci_le_adv_report_evt(hdev, skb);
3406 break;
3407
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003408 case HCI_EV_LE_LTK_REQ:
3409 hci_le_ltk_request_evt(hdev, skb);
3410 break;
3411
Ville Tervofcd89c02011-02-10 22:38:47 -03003412 default:
3413 break;
3414 }
3415}
3416
Linus Torvalds1da177e2005-04-16 15:20:36 -07003417void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3418{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003419 struct hci_event_hdr *hdr = (void *) skb->data;
3420 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003421
3422 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3423
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003424 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003425 case HCI_EV_INQUIRY_COMPLETE:
3426 hci_inquiry_complete_evt(hdev, skb);
3427 break;
3428
3429 case HCI_EV_INQUIRY_RESULT:
3430 hci_inquiry_result_evt(hdev, skb);
3431 break;
3432
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003433 case HCI_EV_CONN_COMPLETE:
3434 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003435 break;
3436
Linus Torvalds1da177e2005-04-16 15:20:36 -07003437 case HCI_EV_CONN_REQUEST:
3438 hci_conn_request_evt(hdev, skb);
3439 break;
3440
Linus Torvalds1da177e2005-04-16 15:20:36 -07003441 case HCI_EV_DISCONN_COMPLETE:
3442 hci_disconn_complete_evt(hdev, skb);
3443 break;
3444
Linus Torvalds1da177e2005-04-16 15:20:36 -07003445 case HCI_EV_AUTH_COMPLETE:
3446 hci_auth_complete_evt(hdev, skb);
3447 break;
3448
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003449 case HCI_EV_REMOTE_NAME:
3450 hci_remote_name_evt(hdev, skb);
3451 break;
3452
Linus Torvalds1da177e2005-04-16 15:20:36 -07003453 case HCI_EV_ENCRYPT_CHANGE:
3454 hci_encrypt_change_evt(hdev, skb);
3455 break;
3456
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003457 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3458 hci_change_link_key_complete_evt(hdev, skb);
3459 break;
3460
3461 case HCI_EV_REMOTE_FEATURES:
3462 hci_remote_features_evt(hdev, skb);
3463 break;
3464
3465 case HCI_EV_REMOTE_VERSION:
3466 hci_remote_version_evt(hdev, skb);
3467 break;
3468
3469 case HCI_EV_QOS_SETUP_COMPLETE:
3470 hci_qos_setup_complete_evt(hdev, skb);
3471 break;
3472
3473 case HCI_EV_CMD_COMPLETE:
3474 hci_cmd_complete_evt(hdev, skb);
3475 break;
3476
3477 case HCI_EV_CMD_STATUS:
3478 hci_cmd_status_evt(hdev, skb);
3479 break;
3480
3481 case HCI_EV_ROLE_CHANGE:
3482 hci_role_change_evt(hdev, skb);
3483 break;
3484
3485 case HCI_EV_NUM_COMP_PKTS:
3486 hci_num_comp_pkts_evt(hdev, skb);
3487 break;
3488
3489 case HCI_EV_MODE_CHANGE:
3490 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003491 break;
3492
3493 case HCI_EV_PIN_CODE_REQ:
3494 hci_pin_code_request_evt(hdev, skb);
3495 break;
3496
3497 case HCI_EV_LINK_KEY_REQ:
3498 hci_link_key_request_evt(hdev, skb);
3499 break;
3500
3501 case HCI_EV_LINK_KEY_NOTIFY:
3502 hci_link_key_notify_evt(hdev, skb);
3503 break;
3504
3505 case HCI_EV_CLOCK_OFFSET:
3506 hci_clock_offset_evt(hdev, skb);
3507 break;
3508
Marcel Holtmanna8746412008-07-14 20:13:46 +02003509 case HCI_EV_PKT_TYPE_CHANGE:
3510 hci_pkt_type_change_evt(hdev, skb);
3511 break;
3512
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003513 case HCI_EV_PSCAN_REP_MODE:
3514 hci_pscan_rep_mode_evt(hdev, skb);
3515 break;
3516
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003517 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3518 hci_inquiry_result_with_rssi_evt(hdev, skb);
3519 break;
3520
3521 case HCI_EV_REMOTE_EXT_FEATURES:
3522 hci_remote_ext_features_evt(hdev, skb);
3523 break;
3524
3525 case HCI_EV_SYNC_CONN_COMPLETE:
3526 hci_sync_conn_complete_evt(hdev, skb);
3527 break;
3528
3529 case HCI_EV_SYNC_CONN_CHANGED:
3530 hci_sync_conn_changed_evt(hdev, skb);
3531 break;
3532
Marcel Holtmann04837f62006-07-03 10:02:33 +02003533 case HCI_EV_SNIFF_SUBRATE:
3534 hci_sniff_subrate_evt(hdev, skb);
3535 break;
3536
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003537 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3538 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003539 break;
3540
Marcel Holtmann04936842008-07-14 20:13:48 +02003541 case HCI_EV_IO_CAPA_REQUEST:
3542 hci_io_capa_request_evt(hdev, skb);
3543 break;
3544
Johan Hedberg03b555e2011-01-04 15:40:05 +02003545 case HCI_EV_IO_CAPA_REPLY:
3546 hci_io_capa_reply_evt(hdev, skb);
3547 break;
3548
Johan Hedberga5c29682011-02-19 12:05:57 -03003549 case HCI_EV_USER_CONFIRM_REQUEST:
3550 hci_user_confirm_request_evt(hdev, skb);
3551 break;
3552
Brian Gix1143d452011-11-23 08:28:34 -08003553 case HCI_EV_USER_PASSKEY_REQUEST:
3554 hci_user_passkey_request_evt(hdev, skb);
3555 break;
3556
Marcel Holtmann04936842008-07-14 20:13:48 +02003557 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3558 hci_simple_pair_complete_evt(hdev, skb);
3559 break;
3560
Marcel Holtmann41a96212008-07-14 20:13:48 +02003561 case HCI_EV_REMOTE_HOST_FEATURES:
3562 hci_remote_host_features_evt(hdev, skb);
3563 break;
3564
Ville Tervofcd89c02011-02-10 22:38:47 -03003565 case HCI_EV_LE_META:
3566 hci_le_meta_evt(hdev, skb);
3567 break;
3568
Szymon Janc2763eda2011-03-22 13:12:22 +01003569 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3570 hci_remote_oob_data_request_evt(hdev, skb);
3571 break;
3572
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003573 case HCI_EV_NUM_COMP_BLOCKS:
3574 hci_num_comp_blocks_evt(hdev, skb);
3575 break;
3576
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003577 default:
3578 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003579 break;
3580 }
3581
3582 kfree_skb(skb);
3583 hdev->stat.evt_rx++;
3584}