blob: 6fb9016652b7c3ec737279a2eb7cde0d88db5a6f [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>
38#include <linux/notifier.h>
39#include <net/sock.h>
40
41#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020042#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <asm/unaligned.h>
44
45#include <net/bluetooth/bluetooth.h>
46#include <net/bluetooth/hci_core.h>
47
Rusty Russelleb939922011-12-19 14:08:01 +000048static bool enable_le;
Andre Guedese6100a22011-06-30 19:20:54 -030049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050/* Handle HCI Event packets */
51
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070053{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020054 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Marcel Holtmanna9de9242007-10-20 13:33:56 +020056 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Andre Guedese6d465c2011-11-09 17:14:26 -030058 if (status) {
59 hci_dev_lock(hdev);
60 mgmt_stop_discovery_failed(hdev, status);
61 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020062 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030063 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Andre Guedes89352e72011-11-04 14:16:53 -030065 clear_bit(HCI_INQUIRY, &hdev->flags);
66
Johan Hedberg56e5cb82011-11-08 20:40:16 +020067 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020068 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020069 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010070
Johan Hedberg23bb5762010-12-21 23:01:27 +020071 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010072
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070074}
75
Marcel Holtmanna9de9242007-10-20 13:33:56 +020076static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070077{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020078 __u8 status = *((__u8 *) skb->data);
79
80 BT_DBG("%s status 0x%x", hdev->name, status);
81
82 if (status)
83 return;
84
Marcel Holtmanna9de9242007-10-20 13:33:56 +020085 hci_conn_check_pending(hdev);
86}
87
88static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
89{
90 BT_DBG("%s", hdev->name);
91}
92
93static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
94{
95 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Marcel Holtmanna9de9242007-10-20 13:33:56 +020098 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 if (rp->status)
101 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200103 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
106 if (conn) {
107 if (rp->role)
108 conn->link_mode &= ~HCI_LM_MASTER;
109 else
110 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200112
113 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114}
115
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200116static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
117{
118 struct hci_rp_read_link_policy *rp = (void *) skb->data;
119 struct hci_conn *conn;
120
121 BT_DBG("%s status 0x%x", hdev->name, rp->status);
122
123 if (rp->status)
124 return;
125
126 hci_dev_lock(hdev);
127
128 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
129 if (conn)
130 conn->link_policy = __le16_to_cpu(rp->policy);
131
132 hci_dev_unlock(hdev);
133}
134
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200137 struct hci_rp_write_link_policy *rp = (void *) skb->data;
138 struct hci_conn *conn;
139 void *sent;
140
141 BT_DBG("%s status 0x%x", hdev->name, rp->status);
142
143 if (rp->status)
144 return;
145
146 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
147 if (!sent)
148 return;
149
150 hci_dev_lock(hdev);
151
152 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200153 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700154 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200155
156 hci_dev_unlock(hdev);
157}
158
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200159static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
160{
161 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
162
163 BT_DBG("%s status 0x%x", hdev->name, rp->status);
164
165 if (rp->status)
166 return;
167
168 hdev->link_policy = __le16_to_cpu(rp->policy);
169}
170
171static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
172{
173 __u8 status = *((__u8 *) skb->data);
174 void *sent;
175
176 BT_DBG("%s status 0x%x", hdev->name, status);
177
178 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
179 if (!sent)
180 return;
181
182 if (!status)
183 hdev->link_policy = get_unaligned_le16(sent);
184
Johan Hedberg23bb5762010-12-21 23:01:27 +0200185 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200186}
187
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200188static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
189{
190 __u8 status = *((__u8 *) skb->data);
191
192 BT_DBG("%s status 0x%x", hdev->name, status);
193
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300194 clear_bit(HCI_RESET, &hdev->flags);
195
Johan Hedberg23bb5762010-12-21 23:01:27 +0200196 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300197
Johan Hedberg7005ff1782012-01-18 16:14:43 +0200198 /* Reset all flags, except persistent ones */
199 hdev->dev_flags &= BIT(HCI_MGMT) | BIT(HCI_SETUP) | BIT(HCI_AUTO_OFF);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200200}
201
202static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
203{
204 __u8 status = *((__u8 *) skb->data);
205 void *sent;
206
207 BT_DBG("%s status 0x%x", hdev->name, status);
208
209 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
210 if (!sent)
211 return;
212
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200213 hci_dev_lock(hdev);
214
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200215 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200216 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 if (status == 0)
219 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200220
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200221 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200222}
223
224static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
225{
226 struct hci_rp_read_local_name *rp = (void *) skb->data;
227
228 BT_DBG("%s status 0x%x", hdev->name, rp->status);
229
230 if (rp->status)
231 return;
232
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200233 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200234}
235
236static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
237{
238 __u8 status = *((__u8 *) skb->data);
239 void *sent;
240
241 BT_DBG("%s status 0x%x", hdev->name, status);
242
243 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
244 if (!sent)
245 return;
246
247 if (!status) {
248 __u8 param = *((__u8 *) sent);
249
250 if (param == AUTH_ENABLED)
251 set_bit(HCI_AUTH, &hdev->flags);
252 else
253 clear_bit(HCI_AUTH, &hdev->flags);
254 }
255
Johan Hedberg23bb5762010-12-21 23:01:27 +0200256 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200257}
258
259static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
260{
261 __u8 status = *((__u8 *) skb->data);
262 void *sent;
263
264 BT_DBG("%s status 0x%x", hdev->name, status);
265
266 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
267 if (!sent)
268 return;
269
270 if (!status) {
271 __u8 param = *((__u8 *) sent);
272
273 if (param)
274 set_bit(HCI_ENCRYPT, &hdev->flags);
275 else
276 clear_bit(HCI_ENCRYPT, &hdev->flags);
277 }
278
Johan Hedberg23bb5762010-12-21 23:01:27 +0200279 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200280}
281
282static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
283{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200284 __u8 param, status = *((__u8 *) skb->data);
285 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200286 void *sent;
287
288 BT_DBG("%s status 0x%x", hdev->name, status);
289
290 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
291 if (!sent)
292 return;
293
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200294 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200295
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200296 hci_dev_lock(hdev);
297
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200298 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200299 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200300 hdev->discov_timeout = 0;
301 goto done;
302 }
303
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200304 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
305 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200306
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200307 if (param & SCAN_INQUIRY) {
308 set_bit(HCI_ISCAN, &hdev->flags);
309 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200310 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200311 if (hdev->discov_timeout > 0) {
312 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
313 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
314 to);
315 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200316 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200317 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200318
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200319 if (param & SCAN_PAGE) {
320 set_bit(HCI_PSCAN, &hdev->flags);
321 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200322 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200324 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200325
326done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200327 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200328 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200329}
330
331static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
332{
333 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
334
335 BT_DBG("%s status 0x%x", hdev->name, rp->status);
336
337 if (rp->status)
338 return;
339
340 memcpy(hdev->dev_class, rp->dev_class, 3);
341
342 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
343 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
344}
345
346static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
347{
348 __u8 status = *((__u8 *) skb->data);
349 void *sent;
350
351 BT_DBG("%s status 0x%x", hdev->name, status);
352
Marcel Holtmannf383f272008-07-14 20:13:47 +0200353 if (status)
354 return;
355
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200356 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
357 if (!sent)
358 return;
359
Marcel Holtmannf383f272008-07-14 20:13:47 +0200360 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200361}
362
363static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
364{
365 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200367
368 BT_DBG("%s status 0x%x", hdev->name, rp->status);
369
370 if (rp->status)
371 return;
372
373 setting = __le16_to_cpu(rp->voice_setting);
374
Marcel Holtmannf383f272008-07-14 20:13:47 +0200375 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200376 return;
377
378 hdev->voice_setting = setting;
379
380 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
381
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200382 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200383 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384}
385
386static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
387{
388 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200389 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 void *sent;
391
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393
Marcel Holtmannf383f272008-07-14 20:13:47 +0200394 if (status)
395 return;
396
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200397 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
398 if (!sent)
399 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
Marcel Holtmannf383f272008-07-14 20:13:47 +0200401 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Marcel Holtmannf383f272008-07-14 20:13:47 +0200403 if (hdev->voice_setting == setting)
404 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405
Marcel Holtmannf383f272008-07-14 20:13:47 +0200406 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
409
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200410 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200411 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412}
413
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200414static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200416 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200418 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
Johan Hedberg23bb5762010-12-21 23:01:27 +0200420 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421}
422
Marcel Holtmann333140b2008-07-14 20:13:48 +0200423static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
424{
425 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
426
427 BT_DBG("%s status 0x%x", hdev->name, rp->status);
428
429 if (rp->status)
430 return;
431
Johan Hedberg84bde9d2012-01-25 14:21:06 +0200432 if (rp->mode)
433 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
434 else
435 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200436}
437
438static 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
445 if (status)
446 return;
447
448 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
449 if (!sent)
450 return;
451
Johan Hedberg84bde9d2012-01-25 14:21:06 +0200452 if (*((u8 *) sent))
453 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
454 else
455 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200456}
457
Johan Hedbergd5859e22011-01-25 01:19:58 +0200458static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
459{
460 if (hdev->features[6] & LMP_EXT_INQ)
461 return 2;
462
463 if (hdev->features[3] & LMP_RSSI_INQ)
464 return 1;
465
466 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
467 hdev->lmp_subver == 0x0757)
468 return 1;
469
470 if (hdev->manufacturer == 15) {
471 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
472 return 1;
473 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
474 return 1;
475 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
476 return 1;
477 }
478
479 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
480 hdev->lmp_subver == 0x1805)
481 return 1;
482
483 return 0;
484}
485
486static void hci_setup_inquiry_mode(struct hci_dev *hdev)
487{
488 u8 mode;
489
490 mode = hci_get_inquiry_mode(hdev);
491
492 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
493}
494
495static void hci_setup_event_mask(struct hci_dev *hdev)
496{
497 /* The second byte is 0xff instead of 0x9f (two reserved bits
498 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
499 * command otherwise */
500 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
501
Ville Tervo6de6c182011-05-27 11:16:21 +0300502 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
503 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200504 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300505 return;
506
507 events[4] |= 0x01; /* Flow Specification Complete */
508 events[4] |= 0x02; /* Inquiry Result with RSSI */
509 events[4] |= 0x04; /* Read Remote Extended Features Complete */
510 events[5] |= 0x08; /* Synchronous Connection Complete */
511 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200512
513 if (hdev->features[3] & LMP_RSSI_INQ)
514 events[4] |= 0x04; /* Inquiry Result with RSSI */
515
516 if (hdev->features[5] & LMP_SNIFF_SUBR)
517 events[5] |= 0x20; /* Sniff Subrating */
518
519 if (hdev->features[5] & LMP_PAUSE_ENC)
520 events[5] |= 0x80; /* Encryption Key Refresh Complete */
521
522 if (hdev->features[6] & LMP_EXT_INQ)
523 events[5] |= 0x40; /* Extended Inquiry Result */
524
525 if (hdev->features[6] & LMP_NO_FLUSH)
526 events[7] |= 0x01; /* Enhanced Flush Complete */
527
528 if (hdev->features[7] & LMP_LSTO)
529 events[6] |= 0x80; /* Link Supervision Timeout Changed */
530
531 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
532 events[6] |= 0x01; /* IO Capability Request */
533 events[6] |= 0x02; /* IO Capability Response */
534 events[6] |= 0x04; /* User Confirmation Request */
535 events[6] |= 0x08; /* User Passkey Request */
536 events[6] |= 0x10; /* Remote OOB Data Request */
537 events[6] |= 0x20; /* Simple Pairing Complete */
538 events[7] |= 0x04; /* User Passkey Notification */
539 events[7] |= 0x08; /* Keypress Notification */
540 events[7] |= 0x10; /* Remote Host Supported
541 * Features Notification */
542 }
543
544 if (hdev->features[4] & LMP_LE)
545 events[7] |= 0x20; /* LE Meta-Event */
546
547 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
548}
549
Andre Guedese6100a22011-06-30 19:20:54 -0300550static void hci_set_le_support(struct hci_dev *hdev)
551{
552 struct hci_cp_write_le_host_supported cp;
553
554 memset(&cp, 0, sizeof(cp));
555
556 if (enable_le) {
557 cp.le = 1;
558 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
559 }
560
561 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
562}
563
Johan Hedbergd5859e22011-01-25 01:19:58 +0200564static void hci_setup(struct hci_dev *hdev)
565{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200566 if (hdev->dev_type != HCI_BREDR)
567 return;
568
Johan Hedbergd5859e22011-01-25 01:19:58 +0200569 hci_setup_event_mask(hdev);
570
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200571 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200572 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
573
574 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
575 u8 mode = 0x01;
576 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
577 }
578
579 if (hdev->features[3] & LMP_RSSI_INQ)
580 hci_setup_inquiry_mode(hdev);
581
582 if (hdev->features[7] & LMP_INQ_TX_PWR)
583 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300584
585 if (hdev->features[7] & LMP_EXTFEATURES) {
586 struct hci_cp_read_local_ext_features cp;
587
588 cp.page = 0x01;
589 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
590 sizeof(cp), &cp);
591 }
Andre Guedese6100a22011-06-30 19:20:54 -0300592
593 if (hdev->features[4] & LMP_LE)
594 hci_set_le_support(hdev);
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)
604 return;
605
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);
618}
619
620static void hci_setup_link_policy(struct hci_dev *hdev)
621{
622 u16 link_policy = 0;
623
624 if (hdev->features[0] & LMP_RSWITCH)
625 link_policy |= HCI_LP_RSWITCH;
626 if (hdev->features[0] & LMP_HOLD)
627 link_policy |= HCI_LP_HOLD;
628 if (hdev->features[0] & LMP_SNIFF)
629 link_policy |= HCI_LP_SNIFF;
630 if (hdev->features[1] & LMP_PARK)
631 link_policy |= HCI_LP_PARK;
632
633 link_policy = cpu_to_le16(link_policy);
634 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
635 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200636}
637
638static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
639{
640 struct hci_rp_read_local_commands *rp = (void *) skb->data;
641
642 BT_DBG("%s status 0x%x", hdev->name, rp->status);
643
644 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200645 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200646
647 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200648
649 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
650 hci_setup_link_policy(hdev);
651
652done:
653 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200654}
655
656static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
657{
658 struct hci_rp_read_local_features *rp = (void *) skb->data;
659
660 BT_DBG("%s status 0x%x", hdev->name, rp->status);
661
662 if (rp->status)
663 return;
664
665 memcpy(hdev->features, rp->features, 8);
666
667 /* Adjust default settings according to features
668 * supported by device. */
669
670 if (hdev->features[0] & LMP_3SLOT)
671 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
672
673 if (hdev->features[0] & LMP_5SLOT)
674 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
675
676 if (hdev->features[1] & LMP_HV2) {
677 hdev->pkt_type |= (HCI_HV2);
678 hdev->esco_type |= (ESCO_HV2);
679 }
680
681 if (hdev->features[1] & LMP_HV3) {
682 hdev->pkt_type |= (HCI_HV3);
683 hdev->esco_type |= (ESCO_HV3);
684 }
685
686 if (hdev->features[3] & LMP_ESCO)
687 hdev->esco_type |= (ESCO_EV3);
688
689 if (hdev->features[4] & LMP_EV4)
690 hdev->esco_type |= (ESCO_EV4);
691
692 if (hdev->features[4] & LMP_EV5)
693 hdev->esco_type |= (ESCO_EV5);
694
Marcel Holtmannefc76882009-02-06 09:13:37 +0100695 if (hdev->features[5] & LMP_EDR_ESCO_2M)
696 hdev->esco_type |= (ESCO_2EV3);
697
698 if (hdev->features[5] & LMP_EDR_ESCO_3M)
699 hdev->esco_type |= (ESCO_3EV3);
700
701 if (hdev->features[5] & LMP_EDR_3S_ESCO)
702 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
703
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200704 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
705 hdev->features[0], hdev->features[1],
706 hdev->features[2], hdev->features[3],
707 hdev->features[4], hdev->features[5],
708 hdev->features[6], hdev->features[7]);
709}
710
Andre Guedes971e3a42011-06-30 19:20:52 -0300711static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
712 struct sk_buff *skb)
713{
714 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
715
716 BT_DBG("%s status 0x%x", hdev->name, rp->status);
717
718 if (rp->status)
719 return;
720
Andre Guedesb5b32b62011-12-30 10:34:04 -0300721 switch (rp->page) {
722 case 0:
723 memcpy(hdev->features, rp->features, 8);
724 break;
725 case 1:
726 memcpy(hdev->host_features, rp->features, 8);
727 break;
728 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300729
730 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
731}
732
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200733static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
734 struct sk_buff *skb)
735{
736 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
737
738 BT_DBG("%s status 0x%x", hdev->name, rp->status);
739
740 if (rp->status)
741 return;
742
743 hdev->flow_ctl_mode = rp->mode;
744
745 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
746}
747
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200748static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
749{
750 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
751
752 BT_DBG("%s status 0x%x", hdev->name, rp->status);
753
754 if (rp->status)
755 return;
756
757 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
758 hdev->sco_mtu = rp->sco_mtu;
759 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
760 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
761
762 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
763 hdev->sco_mtu = 64;
764 hdev->sco_pkts = 8;
765 }
766
767 hdev->acl_cnt = hdev->acl_pkts;
768 hdev->sco_cnt = hdev->sco_pkts;
769
770 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
771 hdev->acl_mtu, hdev->acl_pkts,
772 hdev->sco_mtu, hdev->sco_pkts);
773}
774
775static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
776{
777 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
778
779 BT_DBG("%s status 0x%x", hdev->name, rp->status);
780
781 if (!rp->status)
782 bacpy(&hdev->bdaddr, &rp->bdaddr);
783
Johan Hedberg23bb5762010-12-21 23:01:27 +0200784 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
785}
786
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200787static void hci_cc_read_data_block_size(struct hci_dev *hdev,
788 struct sk_buff *skb)
789{
790 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
791
792 BT_DBG("%s status 0x%x", hdev->name, rp->status);
793
794 if (rp->status)
795 return;
796
797 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
798 hdev->block_len = __le16_to_cpu(rp->block_len);
799 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
800
801 hdev->block_cnt = hdev->num_blocks;
802
803 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
804 hdev->block_cnt, hdev->block_len);
805
806 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
807}
808
Johan Hedberg23bb5762010-12-21 23:01:27 +0200809static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
810{
811 __u8 status = *((__u8 *) skb->data);
812
813 BT_DBG("%s status 0x%x", hdev->name, status);
814
815 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200816}
817
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300818static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
819 struct sk_buff *skb)
820{
821 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
822
823 BT_DBG("%s status 0x%x", hdev->name, rp->status);
824
825 if (rp->status)
826 return;
827
828 hdev->amp_status = rp->amp_status;
829 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
830 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
831 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
832 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
833 hdev->amp_type = rp->amp_type;
834 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
835 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
836 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
837 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
838
839 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
840}
841
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200842static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
843 struct sk_buff *skb)
844{
845 __u8 status = *((__u8 *) skb->data);
846
847 BT_DBG("%s status 0x%x", hdev->name, status);
848
849 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
850}
851
Johan Hedbergd5859e22011-01-25 01:19:58 +0200852static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
853{
854 __u8 status = *((__u8 *) skb->data);
855
856 BT_DBG("%s status 0x%x", hdev->name, status);
857
858 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
859}
860
861static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
862 struct sk_buff *skb)
863{
864 __u8 status = *((__u8 *) skb->data);
865
866 BT_DBG("%s status 0x%x", hdev->name, status);
867
868 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
869}
870
871static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
872 struct sk_buff *skb)
873{
874 __u8 status = *((__u8 *) skb->data);
875
876 BT_DBG("%s status 0x%x", hdev->name, status);
877
878 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
879}
880
881static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
882{
883 __u8 status = *((__u8 *) skb->data);
884
885 BT_DBG("%s status 0x%x", hdev->name, status);
886
887 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
888}
889
Johan Hedberg980e1a52011-01-22 06:10:07 +0200890static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
891{
892 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
893 struct hci_cp_pin_code_reply *cp;
894 struct hci_conn *conn;
895
896 BT_DBG("%s status 0x%x", hdev->name, rp->status);
897
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200898 hci_dev_lock(hdev);
899
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200900 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200901 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200902
903 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200904 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200905
906 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
907 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200908 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200909
910 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
911 if (conn)
912 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200913
914unlock:
915 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200916}
917
918static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
919{
920 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
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_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200928 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200929
930 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200931}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200932
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300933static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
934 struct sk_buff *skb)
935{
936 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
937
938 BT_DBG("%s status 0x%x", hdev->name, rp->status);
939
940 if (rp->status)
941 return;
942
943 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
944 hdev->le_pkts = rp->le_max_pkt;
945
946 hdev->le_cnt = hdev->le_pkts;
947
948 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
949
950 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
951}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200952
Johan Hedberga5c29682011-02-19 12:05:57 -0300953static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
954{
955 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
956
957 BT_DBG("%s status 0x%x", hdev->name, rp->status);
958
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200959 hci_dev_lock(hdev);
960
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200961 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200962 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300963 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200964
965 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300966}
967
968static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
969 struct sk_buff *skb)
970{
971 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
972
973 BT_DBG("%s status 0x%x", hdev->name, rp->status);
974
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200975 hci_dev_lock(hdev);
976
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200977 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200978 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300979 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200980
981 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300982}
983
Brian Gix1143d452011-11-23 08:28:34 -0800984static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
985{
986 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
987
988 BT_DBG("%s status 0x%x", hdev->name, rp->status);
989
990 hci_dev_lock(hdev);
991
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200992 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800993 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr,
994 rp->status);
995
996 hci_dev_unlock(hdev);
997}
998
999static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1000 struct sk_buff *skb)
1001{
1002 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1003
1004 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1005
1006 hci_dev_lock(hdev);
1007
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001008 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001009 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
1010 rp->status);
1011
1012 hci_dev_unlock(hdev);
1013}
1014
Szymon Jancc35938b2011-03-22 13:12:21 +01001015static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1016 struct sk_buff *skb)
1017{
1018 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1019
1020 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1021
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001022 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001023 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001024 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001025 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001026}
1027
Andre Guedes07f7fa52011-12-02 21:13:31 +09001028static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1029{
1030 __u8 status = *((__u8 *) skb->data);
1031
1032 BT_DBG("%s status 0x%x", hdev->name, status);
1033}
1034
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001035static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1036 struct sk_buff *skb)
1037{
1038 struct hci_cp_le_set_scan_enable *cp;
1039 __u8 status = *((__u8 *) skb->data);
1040
1041 BT_DBG("%s status 0x%x", hdev->name, status);
1042
1043 if (status)
1044 return;
1045
1046 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1047 if (!cp)
1048 return;
1049
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001050 switch (cp->enable) {
1051 case LE_SCANNING_ENABLED:
Andre Guedesd23264a2011-11-25 20:53:38 -03001052 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1053
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001054 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001055
1056 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001057 hci_adv_entries_clear(hdev);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001058 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001059 break;
1060
1061 case LE_SCANNING_DISABLED:
Andre Guedesd23264a2011-11-25 20:53:38 -03001062 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1063
Andre Guedesd0843292012-01-02 19:18:11 -03001064 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001065 break;
1066
1067 default:
1068 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1069 break;
Andre Guedes35815082011-05-26 16:23:53 -03001070 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001071}
1072
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001073static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1074{
1075 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1076
1077 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1078
1079 if (rp->status)
1080 return;
1081
1082 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1083}
1084
1085static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1086{
1087 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1088
1089 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1090
1091 if (rp->status)
1092 return;
1093
1094 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1095}
1096
Andre Guedesf9b49302011-06-30 19:20:53 -03001097static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1098 struct sk_buff *skb)
1099{
1100 struct hci_cp_read_local_ext_features cp;
1101 __u8 status = *((__u8 *) skb->data);
1102
1103 BT_DBG("%s status 0x%x", hdev->name, status);
1104
1105 if (status)
1106 return;
1107
1108 cp.page = 0x01;
1109 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1110}
1111
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001112static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1113{
1114 BT_DBG("%s status 0x%x", hdev->name, status);
1115
1116 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001117 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001118 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001119 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001120 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001121 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001122 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001123 return;
1124 }
1125
Andre Guedes89352e72011-11-04 14:16:53 -03001126 set_bit(HCI_INQUIRY, &hdev->flags);
1127
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001128 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001129 hci_discovery_set_state(hdev, DISCOVERY_INQUIRY);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001130 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001131}
1132
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1134{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001135 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001138 BT_DBG("%s status 0x%x", hdev->name, status);
1139
1140 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 if (!cp)
1142 return;
1143
1144 hci_dev_lock(hdev);
1145
1146 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1147
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001148 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149
1150 if (status) {
1151 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001152 if (status != 0x0c || conn->attempt > 2) {
1153 conn->state = BT_CLOSED;
1154 hci_proto_connect_cfm(conn, status);
1155 hci_conn_del(conn);
1156 } else
1157 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 }
1159 } else {
1160 if (!conn) {
1161 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1162 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001163 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 conn->link_mode |= HCI_LM_MASTER;
1165 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001166 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167 }
1168 }
1169
1170 hci_dev_unlock(hdev);
1171}
1172
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001173static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001175 struct hci_cp_add_sco *cp;
1176 struct hci_conn *acl, *sco;
1177 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001179 BT_DBG("%s status 0x%x", hdev->name, status);
1180
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001181 if (!status)
1182 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001184 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1185 if (!cp)
1186 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001188 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001190 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001191
1192 hci_dev_lock(hdev);
1193
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001194 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001195 if (acl) {
1196 sco = acl->link;
1197 if (sco) {
1198 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001199
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001200 hci_proto_connect_cfm(sco, status);
1201 hci_conn_del(sco);
1202 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001203 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001204
1205 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206}
1207
Marcel Holtmannf8558552008-07-14 20:13:49 +02001208static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1209{
1210 struct hci_cp_auth_requested *cp;
1211 struct hci_conn *conn;
1212
1213 BT_DBG("%s status 0x%x", hdev->name, status);
1214
1215 if (!status)
1216 return;
1217
1218 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1219 if (!cp)
1220 return;
1221
1222 hci_dev_lock(hdev);
1223
1224 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1225 if (conn) {
1226 if (conn->state == BT_CONFIG) {
1227 hci_proto_connect_cfm(conn, status);
1228 hci_conn_put(conn);
1229 }
1230 }
1231
1232 hci_dev_unlock(hdev);
1233}
1234
1235static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1236{
1237 struct hci_cp_set_conn_encrypt *cp;
1238 struct hci_conn *conn;
1239
1240 BT_DBG("%s status 0x%x", hdev->name, status);
1241
1242 if (!status)
1243 return;
1244
1245 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1246 if (!cp)
1247 return;
1248
1249 hci_dev_lock(hdev);
1250
1251 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1252 if (conn) {
1253 if (conn->state == BT_CONFIG) {
1254 hci_proto_connect_cfm(conn, status);
1255 hci_conn_put(conn);
1256 }
1257 }
1258
1259 hci_dev_unlock(hdev);
1260}
1261
Johan Hedberg127178d2010-11-18 22:22:29 +02001262static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001263 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001264{
Johan Hedberg392599b2010-11-18 22:22:28 +02001265 if (conn->state != BT_CONFIG || !conn->out)
1266 return 0;
1267
Johan Hedberg765c2a92011-01-19 12:06:52 +05301268 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001269 return 0;
1270
1271 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001272 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001273 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001274 conn->pending_sec_level != BT_SECURITY_HIGH &&
1275 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001276 return 0;
1277
Johan Hedberg392599b2010-11-18 22:22:28 +02001278 return 1;
1279}
1280
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001281static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1282{
1283 struct hci_cp_remote_name_req cp;
1284
1285 memset(&cp, 0, sizeof(cp));
1286
1287 bacpy(&cp.bdaddr, &e->data.bdaddr);
1288 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1289 cp.pscan_mode = e->data.pscan_mode;
1290 cp.clock_offset = e->data.clock_offset;
1291
1292 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1293}
1294
Johan Hedbergb644ba32012-01-17 21:48:47 +02001295static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001296{
1297 struct discovery_state *discov = &hdev->discovery;
1298 struct inquiry_entry *e;
1299
Johan Hedbergb644ba32012-01-17 21:48:47 +02001300 if (list_empty(&discov->resolve))
1301 return false;
1302
1303 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1304 if (hci_resolve_name(hdev, e) == 0) {
1305 e->name_state = NAME_PENDING;
1306 return true;
1307 }
1308
1309 return false;
1310}
1311
1312static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1313 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1314{
1315 struct discovery_state *discov = &hdev->discovery;
1316 struct inquiry_entry *e;
1317
1318 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1319 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
1320 name, name_len, conn->dev_class);
1321
1322 if (discov->state == DISCOVERY_STOPPED)
1323 return;
1324
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001325 if (discov->state == DISCOVERY_STOPPING)
1326 goto discov_complete;
1327
1328 if (discov->state != DISCOVERY_RESOLVING)
1329 return;
1330
1331 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1332 if (e) {
1333 e->name_state = NAME_KNOWN;
1334 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001335 if (name)
1336 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1337 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001338 }
1339
Johan Hedbergb644ba32012-01-17 21:48:47 +02001340 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001341 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001342
1343discov_complete:
1344 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1345}
1346
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001347static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1348{
Johan Hedberg127178d2010-11-18 22:22:29 +02001349 struct hci_cp_remote_name_req *cp;
1350 struct hci_conn *conn;
1351
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001352 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001353
1354 /* If successful wait for the name req complete event before
1355 * checking for the need to do authentication */
1356 if (!status)
1357 return;
1358
1359 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1360 if (!cp)
1361 return;
1362
1363 hci_dev_lock(hdev);
1364
1365 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001366
1367 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1368 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1369
Johan Hedberg79c6c702011-04-28 11:28:55 -07001370 if (!conn)
1371 goto unlock;
1372
1373 if (!hci_outgoing_auth_needed(hdev, conn))
1374 goto unlock;
1375
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001376 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001377 struct hci_cp_auth_requested cp;
1378 cp.handle = __cpu_to_le16(conn->handle);
1379 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1380 }
1381
Johan Hedberg79c6c702011-04-28 11:28:55 -07001382unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001383 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001384}
1385
Marcel Holtmann769be972008-07-14 20:13:49 +02001386static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1387{
1388 struct hci_cp_read_remote_features *cp;
1389 struct hci_conn *conn;
1390
1391 BT_DBG("%s status 0x%x", hdev->name, status);
1392
1393 if (!status)
1394 return;
1395
1396 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1397 if (!cp)
1398 return;
1399
1400 hci_dev_lock(hdev);
1401
1402 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1403 if (conn) {
1404 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001405 hci_proto_connect_cfm(conn, status);
1406 hci_conn_put(conn);
1407 }
1408 }
1409
1410 hci_dev_unlock(hdev);
1411}
1412
1413static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1414{
1415 struct hci_cp_read_remote_ext_features *cp;
1416 struct hci_conn *conn;
1417
1418 BT_DBG("%s status 0x%x", hdev->name, status);
1419
1420 if (!status)
1421 return;
1422
1423 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1424 if (!cp)
1425 return;
1426
1427 hci_dev_lock(hdev);
1428
1429 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1430 if (conn) {
1431 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001432 hci_proto_connect_cfm(conn, status);
1433 hci_conn_put(conn);
1434 }
1435 }
1436
1437 hci_dev_unlock(hdev);
1438}
1439
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001440static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1441{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001442 struct hci_cp_setup_sync_conn *cp;
1443 struct hci_conn *acl, *sco;
1444 __u16 handle;
1445
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001446 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001447
1448 if (!status)
1449 return;
1450
1451 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1452 if (!cp)
1453 return;
1454
1455 handle = __le16_to_cpu(cp->handle);
1456
1457 BT_DBG("%s handle %d", hdev->name, handle);
1458
1459 hci_dev_lock(hdev);
1460
1461 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001462 if (acl) {
1463 sco = acl->link;
1464 if (sco) {
1465 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001466
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001467 hci_proto_connect_cfm(sco, status);
1468 hci_conn_del(sco);
1469 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001470 }
1471
1472 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001473}
1474
1475static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1476{
1477 struct hci_cp_sniff_mode *cp;
1478 struct hci_conn *conn;
1479
1480 BT_DBG("%s status 0x%x", hdev->name, status);
1481
1482 if (!status)
1483 return;
1484
1485 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1486 if (!cp)
1487 return;
1488
1489 hci_dev_lock(hdev);
1490
1491 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001492 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001493 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001494
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001495 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001496 hci_sco_setup(conn, status);
1497 }
1498
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001499 hci_dev_unlock(hdev);
1500}
1501
1502static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1503{
1504 struct hci_cp_exit_sniff_mode *cp;
1505 struct hci_conn *conn;
1506
1507 BT_DBG("%s status 0x%x", hdev->name, status);
1508
1509 if (!status)
1510 return;
1511
1512 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1513 if (!cp)
1514 return;
1515
1516 hci_dev_lock(hdev);
1517
1518 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001519 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001520 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001521
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001522 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001523 hci_sco_setup(conn, status);
1524 }
1525
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001526 hci_dev_unlock(hdev);
1527}
1528
Ville Tervofcd89c02011-02-10 22:38:47 -03001529static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1530{
1531 struct hci_cp_le_create_conn *cp;
1532 struct hci_conn *conn;
1533
1534 BT_DBG("%s status 0x%x", hdev->name, status);
1535
1536 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1537 if (!cp)
1538 return;
1539
1540 hci_dev_lock(hdev);
1541
1542 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1543
1544 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1545 conn);
1546
1547 if (status) {
1548 if (conn && conn->state == BT_CONNECT) {
1549 conn->state = BT_CLOSED;
1550 hci_proto_connect_cfm(conn, status);
1551 hci_conn_del(conn);
1552 }
1553 } else {
1554 if (!conn) {
1555 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001556 if (conn) {
1557 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001558 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001559 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001560 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001561 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001562 }
1563 }
1564
1565 hci_dev_unlock(hdev);
1566}
1567
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001568static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1569{
1570 BT_DBG("%s status 0x%x", hdev->name, status);
1571}
1572
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001573static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1574{
1575 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001576 struct discovery_state *discov = &hdev->discovery;
1577 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001578
1579 BT_DBG("%s status %d", hdev->name, status);
1580
Johan Hedberg23bb5762010-12-21 23:01:27 +02001581 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001582
1583 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001584
1585 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1586 return;
1587
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001588 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001589 return;
1590
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001591 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001592
1593 if (discov->state != DISCOVERY_INQUIRY)
1594 goto unlock;
1595
1596 if (list_empty(&discov->resolve)) {
1597 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1598 goto unlock;
1599 }
1600
1601 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1602 if (e && hci_resolve_name(hdev, e) == 0) {
1603 e->name_state = NAME_PENDING;
1604 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1605 } else {
1606 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1607 }
1608
1609unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001610 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001611}
1612
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1614{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001615 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001616 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 int num_rsp = *((__u8 *) skb->data);
1618
1619 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1620
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001621 if (!num_rsp)
1622 return;
1623
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001625
Johan Hedberge17acd42011-03-30 23:57:16 +03001626 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg31754052012-01-04 13:39:52 +02001627 bool name_known;
1628
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 bacpy(&data.bdaddr, &info->bdaddr);
1630 data.pscan_rep_mode = info->pscan_rep_mode;
1631 data.pscan_period_mode = info->pscan_period_mode;
1632 data.pscan_mode = info->pscan_mode;
1633 memcpy(data.dev_class, info->dev_class, 3);
1634 data.clock_offset = info->clock_offset;
1635 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001636 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001637
1638 name_known = hci_inquiry_cache_update(hdev, &data, false);
Johan Hedberg48264f02011-11-09 13:58:58 +02001639 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Andre Guedes7d262f82012-01-10 18:20:49 -03001640 info->dev_class, 0, !name_known,
1641 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001643
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 hci_dev_unlock(hdev);
1645}
1646
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001647static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001649 struct hci_ev_conn_complete *ev = (void *) skb->data;
1650 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001652 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001653
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001655
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001656 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001657 if (!conn) {
1658 if (ev->link_type != SCO_LINK)
1659 goto unlock;
1660
1661 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1662 if (!conn)
1663 goto unlock;
1664
1665 conn->type = SCO_LINK;
1666 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001667
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001668 if (!ev->status) {
1669 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001670
1671 if (conn->type == ACL_LINK) {
1672 conn->state = BT_CONFIG;
1673 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001674 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001675 } else
1676 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001677
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001678 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001679 hci_conn_add_sysfs(conn);
1680
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001681 if (test_bit(HCI_AUTH, &hdev->flags))
1682 conn->link_mode |= HCI_LM_AUTH;
1683
1684 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1685 conn->link_mode |= HCI_LM_ENCRYPT;
1686
1687 /* Get remote features */
1688 if (conn->type == ACL_LINK) {
1689 struct hci_cp_read_remote_features cp;
1690 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001691 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1692 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001693 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001694
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001695 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001696 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001697 struct hci_cp_change_conn_ptype cp;
1698 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001699 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1700 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1701 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001702 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001703 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001704 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001705 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001706 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001707 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001708 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001709
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001710 if (conn->type == ACL_LINK)
1711 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001712
Marcel Holtmann769be972008-07-14 20:13:49 +02001713 if (ev->status) {
1714 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001715 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001716 } else if (ev->link_type != ACL_LINK)
1717 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001718
1719unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001721
1722 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723}
1724
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1726{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001727 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728 int mask = hdev->link_mode;
1729
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001730 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1731 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732
1733 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1734
Szymon Janc138d22e2011-02-17 16:44:23 +01001735 if ((mask & HCI_LM_ACCEPT) &&
1736 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001738 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
1741 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001742
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001743 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1744 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001745 memcpy(ie->data.dev_class, ev->dev_class, 3);
1746
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1748 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001749 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1750 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001751 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 hci_dev_unlock(hdev);
1753 return;
1754 }
1755 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001756
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 memcpy(conn->dev_class, ev->dev_class, 3);
1758 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001759
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 hci_dev_unlock(hdev);
1761
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001762 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1763 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001765 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001767 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1768 cp.role = 0x00; /* Become master */
1769 else
1770 cp.role = 0x01; /* Remain slave */
1771
1772 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1773 sizeof(cp), &cp);
1774 } else {
1775 struct hci_cp_accept_sync_conn_req cp;
1776
1777 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001778 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001779
1780 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1781 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1782 cp.max_latency = cpu_to_le16(0xffff);
1783 cp.content_format = cpu_to_le16(hdev->voice_setting);
1784 cp.retrans_effort = 0xff;
1785
1786 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1787 sizeof(cp), &cp);
1788 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789 } else {
1790 /* Connection rejected */
1791 struct hci_cp_reject_conn_req cp;
1792
1793 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001794 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001795 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 }
1797}
1798
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1800{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001801 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001802 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803
1804 BT_DBG("%s status %d", hdev->name, ev->status);
1805
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 hci_dev_lock(hdev);
1807
Marcel Holtmann04837f62006-07-03 10:02:33 +02001808 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001809 if (!conn)
1810 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001811
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001812 if (ev->status == 0)
1813 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814
Johan Hedbergb644ba32012-01-17 21:48:47 +02001815 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1816 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001817 if (ev->status != 0)
1818 mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
1819 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001820 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001821 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001822 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001823
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001824 if (ev->status == 0) {
1825 hci_proto_disconn_cfm(conn, ev->reason);
1826 hci_conn_del(conn);
1827 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001828
1829unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 hci_dev_unlock(hdev);
1831}
1832
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001833static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1834{
1835 struct hci_ev_auth_complete *ev = (void *) skb->data;
1836 struct hci_conn *conn;
1837
1838 BT_DBG("%s status %d", hdev->name, ev->status);
1839
1840 hci_dev_lock(hdev);
1841
1842 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001843 if (!conn)
1844 goto unlock;
1845
1846 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001847 if (!hci_conn_ssp_enabled(conn) &&
1848 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001849 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001850 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001851 conn->link_mode |= HCI_LM_AUTH;
1852 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001853 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001854 } else {
Johan Hedberg744cf192011-11-08 20:40:14 +02001855 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001856 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001857
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001858 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1859 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001860
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001861 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001862 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001863 struct hci_cp_set_conn_encrypt cp;
1864 cp.handle = ev->handle;
1865 cp.encrypt = 0x01;
1866 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1867 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001868 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001869 conn->state = BT_CONNECTED;
1870 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001871 hci_conn_put(conn);
1872 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001873 } else {
1874 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001875
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001876 hci_conn_hold(conn);
1877 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1878 hci_conn_put(conn);
1879 }
1880
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001881 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001882 if (!ev->status) {
1883 struct hci_cp_set_conn_encrypt cp;
1884 cp.handle = ev->handle;
1885 cp.encrypt = 0x01;
1886 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1887 &cp);
1888 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001889 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001890 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001891 }
1892 }
1893
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001894unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001895 hci_dev_unlock(hdev);
1896}
1897
1898static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1899{
Johan Hedberg127178d2010-11-18 22:22:29 +02001900 struct hci_ev_remote_name *ev = (void *) skb->data;
1901 struct hci_conn *conn;
1902
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001903 BT_DBG("%s", hdev->name);
1904
1905 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001906
1907 hci_dev_lock(hdev);
1908
1909 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001910
1911 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1912 goto check_auth;
1913
1914 if (ev->status == 0)
1915 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1916 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1917 else
1918 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1919
1920check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001921 if (!conn)
1922 goto unlock;
1923
1924 if (!hci_outgoing_auth_needed(hdev, conn))
1925 goto unlock;
1926
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001927 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001928 struct hci_cp_auth_requested cp;
1929 cp.handle = __cpu_to_le16(conn->handle);
1930 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1931 }
1932
Johan Hedberg79c6c702011-04-28 11:28:55 -07001933unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001934 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001935}
1936
1937static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1938{
1939 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1940 struct hci_conn *conn;
1941
1942 BT_DBG("%s status %d", hdev->name, ev->status);
1943
1944 hci_dev_lock(hdev);
1945
1946 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1947 if (conn) {
1948 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001949 if (ev->encrypt) {
1950 /* Encryption implies authentication */
1951 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001952 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001953 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001954 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001955 conn->link_mode &= ~HCI_LM_ENCRYPT;
1956 }
1957
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001958 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001959
Marcel Holtmannf8558552008-07-14 20:13:49 +02001960 if (conn->state == BT_CONFIG) {
1961 if (!ev->status)
1962 conn->state = BT_CONNECTED;
1963
1964 hci_proto_connect_cfm(conn, ev->status);
1965 hci_conn_put(conn);
1966 } else
1967 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001968 }
1969
1970 hci_dev_unlock(hdev);
1971}
1972
1973static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1974{
1975 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1976 struct hci_conn *conn;
1977
1978 BT_DBG("%s status %d", hdev->name, ev->status);
1979
1980 hci_dev_lock(hdev);
1981
1982 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1983 if (conn) {
1984 if (!ev->status)
1985 conn->link_mode |= HCI_LM_SECURE;
1986
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001987 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001988
1989 hci_key_change_cfm(conn, ev->status);
1990 }
1991
1992 hci_dev_unlock(hdev);
1993}
1994
1995static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1996{
1997 struct hci_ev_remote_features *ev = (void *) skb->data;
1998 struct hci_conn *conn;
1999
2000 BT_DBG("%s status %d", hdev->name, ev->status);
2001
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002002 hci_dev_lock(hdev);
2003
2004 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002005 if (!conn)
2006 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002007
Johan Hedbergccd556f2010-11-10 17:11:51 +02002008 if (!ev->status)
2009 memcpy(conn->features, ev->features, 8);
2010
2011 if (conn->state != BT_CONFIG)
2012 goto unlock;
2013
2014 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2015 struct hci_cp_read_remote_ext_features cp;
2016 cp.handle = ev->handle;
2017 cp.page = 0x01;
2018 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002019 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002020 goto unlock;
2021 }
2022
Johan Hedberg127178d2010-11-18 22:22:29 +02002023 if (!ev->status) {
2024 struct hci_cp_remote_name_req cp;
2025 memset(&cp, 0, sizeof(cp));
2026 bacpy(&cp.bdaddr, &conn->dst);
2027 cp.pscan_rep_mode = 0x02;
2028 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002029 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2030 mgmt_device_connected(hdev, &conn->dst, conn->type,
2031 conn->dst_type, NULL, 0,
2032 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002033
Johan Hedberg127178d2010-11-18 22:22:29 +02002034 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002035 conn->state = BT_CONNECTED;
2036 hci_proto_connect_cfm(conn, ev->status);
2037 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002038 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002039
Johan Hedbergccd556f2010-11-10 17:11:51 +02002040unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002041 hci_dev_unlock(hdev);
2042}
2043
2044static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2045{
2046 BT_DBG("%s", hdev->name);
2047}
2048
2049static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2050{
2051 BT_DBG("%s", hdev->name);
2052}
2053
2054static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2055{
2056 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2057 __u16 opcode;
2058
2059 skb_pull(skb, sizeof(*ev));
2060
2061 opcode = __le16_to_cpu(ev->opcode);
2062
2063 switch (opcode) {
2064 case HCI_OP_INQUIRY_CANCEL:
2065 hci_cc_inquiry_cancel(hdev, skb);
2066 break;
2067
2068 case HCI_OP_EXIT_PERIODIC_INQ:
2069 hci_cc_exit_periodic_inq(hdev, skb);
2070 break;
2071
2072 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2073 hci_cc_remote_name_req_cancel(hdev, skb);
2074 break;
2075
2076 case HCI_OP_ROLE_DISCOVERY:
2077 hci_cc_role_discovery(hdev, skb);
2078 break;
2079
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002080 case HCI_OP_READ_LINK_POLICY:
2081 hci_cc_read_link_policy(hdev, skb);
2082 break;
2083
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002084 case HCI_OP_WRITE_LINK_POLICY:
2085 hci_cc_write_link_policy(hdev, skb);
2086 break;
2087
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002088 case HCI_OP_READ_DEF_LINK_POLICY:
2089 hci_cc_read_def_link_policy(hdev, skb);
2090 break;
2091
2092 case HCI_OP_WRITE_DEF_LINK_POLICY:
2093 hci_cc_write_def_link_policy(hdev, skb);
2094 break;
2095
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002096 case HCI_OP_RESET:
2097 hci_cc_reset(hdev, skb);
2098 break;
2099
2100 case HCI_OP_WRITE_LOCAL_NAME:
2101 hci_cc_write_local_name(hdev, skb);
2102 break;
2103
2104 case HCI_OP_READ_LOCAL_NAME:
2105 hci_cc_read_local_name(hdev, skb);
2106 break;
2107
2108 case HCI_OP_WRITE_AUTH_ENABLE:
2109 hci_cc_write_auth_enable(hdev, skb);
2110 break;
2111
2112 case HCI_OP_WRITE_ENCRYPT_MODE:
2113 hci_cc_write_encrypt_mode(hdev, skb);
2114 break;
2115
2116 case HCI_OP_WRITE_SCAN_ENABLE:
2117 hci_cc_write_scan_enable(hdev, skb);
2118 break;
2119
2120 case HCI_OP_READ_CLASS_OF_DEV:
2121 hci_cc_read_class_of_dev(hdev, skb);
2122 break;
2123
2124 case HCI_OP_WRITE_CLASS_OF_DEV:
2125 hci_cc_write_class_of_dev(hdev, skb);
2126 break;
2127
2128 case HCI_OP_READ_VOICE_SETTING:
2129 hci_cc_read_voice_setting(hdev, skb);
2130 break;
2131
2132 case HCI_OP_WRITE_VOICE_SETTING:
2133 hci_cc_write_voice_setting(hdev, skb);
2134 break;
2135
2136 case HCI_OP_HOST_BUFFER_SIZE:
2137 hci_cc_host_buffer_size(hdev, skb);
2138 break;
2139
Marcel Holtmann333140b2008-07-14 20:13:48 +02002140 case HCI_OP_READ_SSP_MODE:
2141 hci_cc_read_ssp_mode(hdev, skb);
2142 break;
2143
2144 case HCI_OP_WRITE_SSP_MODE:
2145 hci_cc_write_ssp_mode(hdev, skb);
2146 break;
2147
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002148 case HCI_OP_READ_LOCAL_VERSION:
2149 hci_cc_read_local_version(hdev, skb);
2150 break;
2151
2152 case HCI_OP_READ_LOCAL_COMMANDS:
2153 hci_cc_read_local_commands(hdev, skb);
2154 break;
2155
2156 case HCI_OP_READ_LOCAL_FEATURES:
2157 hci_cc_read_local_features(hdev, skb);
2158 break;
2159
Andre Guedes971e3a42011-06-30 19:20:52 -03002160 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2161 hci_cc_read_local_ext_features(hdev, skb);
2162 break;
2163
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002164 case HCI_OP_READ_BUFFER_SIZE:
2165 hci_cc_read_buffer_size(hdev, skb);
2166 break;
2167
2168 case HCI_OP_READ_BD_ADDR:
2169 hci_cc_read_bd_addr(hdev, skb);
2170 break;
2171
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002172 case HCI_OP_READ_DATA_BLOCK_SIZE:
2173 hci_cc_read_data_block_size(hdev, skb);
2174 break;
2175
Johan Hedberg23bb5762010-12-21 23:01:27 +02002176 case HCI_OP_WRITE_CA_TIMEOUT:
2177 hci_cc_write_ca_timeout(hdev, skb);
2178 break;
2179
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002180 case HCI_OP_READ_FLOW_CONTROL_MODE:
2181 hci_cc_read_flow_control_mode(hdev, skb);
2182 break;
2183
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002184 case HCI_OP_READ_LOCAL_AMP_INFO:
2185 hci_cc_read_local_amp_info(hdev, skb);
2186 break;
2187
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002188 case HCI_OP_DELETE_STORED_LINK_KEY:
2189 hci_cc_delete_stored_link_key(hdev, skb);
2190 break;
2191
Johan Hedbergd5859e22011-01-25 01:19:58 +02002192 case HCI_OP_SET_EVENT_MASK:
2193 hci_cc_set_event_mask(hdev, skb);
2194 break;
2195
2196 case HCI_OP_WRITE_INQUIRY_MODE:
2197 hci_cc_write_inquiry_mode(hdev, skb);
2198 break;
2199
2200 case HCI_OP_READ_INQ_RSP_TX_POWER:
2201 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2202 break;
2203
2204 case HCI_OP_SET_EVENT_FLT:
2205 hci_cc_set_event_flt(hdev, skb);
2206 break;
2207
Johan Hedberg980e1a52011-01-22 06:10:07 +02002208 case HCI_OP_PIN_CODE_REPLY:
2209 hci_cc_pin_code_reply(hdev, skb);
2210 break;
2211
2212 case HCI_OP_PIN_CODE_NEG_REPLY:
2213 hci_cc_pin_code_neg_reply(hdev, skb);
2214 break;
2215
Szymon Jancc35938b2011-03-22 13:12:21 +01002216 case HCI_OP_READ_LOCAL_OOB_DATA:
2217 hci_cc_read_local_oob_data_reply(hdev, skb);
2218 break;
2219
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002220 case HCI_OP_LE_READ_BUFFER_SIZE:
2221 hci_cc_le_read_buffer_size(hdev, skb);
2222 break;
2223
Johan Hedberga5c29682011-02-19 12:05:57 -03002224 case HCI_OP_USER_CONFIRM_REPLY:
2225 hci_cc_user_confirm_reply(hdev, skb);
2226 break;
2227
2228 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2229 hci_cc_user_confirm_neg_reply(hdev, skb);
2230 break;
2231
Brian Gix1143d452011-11-23 08:28:34 -08002232 case HCI_OP_USER_PASSKEY_REPLY:
2233 hci_cc_user_passkey_reply(hdev, skb);
2234 break;
2235
2236 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2237 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002238
2239 case HCI_OP_LE_SET_SCAN_PARAM:
2240 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002241 break;
2242
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002243 case HCI_OP_LE_SET_SCAN_ENABLE:
2244 hci_cc_le_set_scan_enable(hdev, skb);
2245 break;
2246
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002247 case HCI_OP_LE_LTK_REPLY:
2248 hci_cc_le_ltk_reply(hdev, skb);
2249 break;
2250
2251 case HCI_OP_LE_LTK_NEG_REPLY:
2252 hci_cc_le_ltk_neg_reply(hdev, skb);
2253 break;
2254
Andre Guedesf9b49302011-06-30 19:20:53 -03002255 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2256 hci_cc_write_le_host_supported(hdev, skb);
2257 break;
2258
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002259 default:
2260 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2261 break;
2262 }
2263
Ville Tervo6bd32322011-02-16 16:32:41 +02002264 if (ev->opcode != HCI_OP_NOP)
2265 del_timer(&hdev->cmd_timer);
2266
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002267 if (ev->ncmd) {
2268 atomic_set(&hdev->cmd_cnt, 1);
2269 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002270 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002271 }
2272}
2273
2274static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2275{
2276 struct hci_ev_cmd_status *ev = (void *) skb->data;
2277 __u16 opcode;
2278
2279 skb_pull(skb, sizeof(*ev));
2280
2281 opcode = __le16_to_cpu(ev->opcode);
2282
2283 switch (opcode) {
2284 case HCI_OP_INQUIRY:
2285 hci_cs_inquiry(hdev, ev->status);
2286 break;
2287
2288 case HCI_OP_CREATE_CONN:
2289 hci_cs_create_conn(hdev, ev->status);
2290 break;
2291
2292 case HCI_OP_ADD_SCO:
2293 hci_cs_add_sco(hdev, ev->status);
2294 break;
2295
Marcel Holtmannf8558552008-07-14 20:13:49 +02002296 case HCI_OP_AUTH_REQUESTED:
2297 hci_cs_auth_requested(hdev, ev->status);
2298 break;
2299
2300 case HCI_OP_SET_CONN_ENCRYPT:
2301 hci_cs_set_conn_encrypt(hdev, ev->status);
2302 break;
2303
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002304 case HCI_OP_REMOTE_NAME_REQ:
2305 hci_cs_remote_name_req(hdev, ev->status);
2306 break;
2307
Marcel Holtmann769be972008-07-14 20:13:49 +02002308 case HCI_OP_READ_REMOTE_FEATURES:
2309 hci_cs_read_remote_features(hdev, ev->status);
2310 break;
2311
2312 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2313 hci_cs_read_remote_ext_features(hdev, ev->status);
2314 break;
2315
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002316 case HCI_OP_SETUP_SYNC_CONN:
2317 hci_cs_setup_sync_conn(hdev, ev->status);
2318 break;
2319
2320 case HCI_OP_SNIFF_MODE:
2321 hci_cs_sniff_mode(hdev, ev->status);
2322 break;
2323
2324 case HCI_OP_EXIT_SNIFF_MODE:
2325 hci_cs_exit_sniff_mode(hdev, ev->status);
2326 break;
2327
Johan Hedberg8962ee72011-01-20 12:40:27 +02002328 case HCI_OP_DISCONNECT:
2329 if (ev->status != 0)
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002330 mgmt_disconnect_failed(hdev, NULL, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002331 break;
2332
Ville Tervofcd89c02011-02-10 22:38:47 -03002333 case HCI_OP_LE_CREATE_CONN:
2334 hci_cs_le_create_conn(hdev, ev->status);
2335 break;
2336
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002337 case HCI_OP_LE_START_ENC:
2338 hci_cs_le_start_enc(hdev, ev->status);
2339 break;
2340
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002341 default:
2342 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2343 break;
2344 }
2345
Ville Tervo6bd32322011-02-16 16:32:41 +02002346 if (ev->opcode != HCI_OP_NOP)
2347 del_timer(&hdev->cmd_timer);
2348
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002349 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002350 atomic_set(&hdev->cmd_cnt, 1);
2351 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002352 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002353 }
2354}
2355
2356static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2357{
2358 struct hci_ev_role_change *ev = (void *) skb->data;
2359 struct hci_conn *conn;
2360
2361 BT_DBG("%s status %d", hdev->name, ev->status);
2362
2363 hci_dev_lock(hdev);
2364
2365 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2366 if (conn) {
2367 if (!ev->status) {
2368 if (ev->role)
2369 conn->link_mode &= ~HCI_LM_MASTER;
2370 else
2371 conn->link_mode |= HCI_LM_MASTER;
2372 }
2373
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002374 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002375
2376 hci_role_switch_cfm(conn, ev->status, ev->role);
2377 }
2378
2379 hci_dev_unlock(hdev);
2380}
2381
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2383{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002384 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002385 int i;
2386
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002387 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2388 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2389 return;
2390 }
2391
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002392 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2393 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394 BT_DBG("%s bad parameters", hdev->name);
2395 return;
2396 }
2397
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002398 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2399
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002400 for (i = 0; i < ev->num_hndl; i++) {
2401 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002402 struct hci_conn *conn;
2403 __u16 handle, count;
2404
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002405 handle = __le16_to_cpu(info->handle);
2406 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002407
2408 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002409 if (!conn)
2410 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002412 conn->sent -= count;
2413
2414 switch (conn->type) {
2415 case ACL_LINK:
2416 hdev->acl_cnt += count;
2417 if (hdev->acl_cnt > hdev->acl_pkts)
2418 hdev->acl_cnt = hdev->acl_pkts;
2419 break;
2420
2421 case LE_LINK:
2422 if (hdev->le_pkts) {
2423 hdev->le_cnt += count;
2424 if (hdev->le_cnt > hdev->le_pkts)
2425 hdev->le_cnt = hdev->le_pkts;
2426 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002427 hdev->acl_cnt += count;
2428 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002429 hdev->acl_cnt = hdev->acl_pkts;
2430 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002431 break;
2432
2433 case SCO_LINK:
2434 hdev->sco_cnt += count;
2435 if (hdev->sco_cnt > hdev->sco_pkts)
2436 hdev->sco_cnt = hdev->sco_pkts;
2437 break;
2438
2439 default:
2440 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2441 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442 }
2443 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002444
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002445 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446}
2447
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002448static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2449 struct sk_buff *skb)
2450{
2451 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2452 int i;
2453
2454 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2455 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2456 return;
2457 }
2458
2459 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2460 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2461 BT_DBG("%s bad parameters", hdev->name);
2462 return;
2463 }
2464
2465 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2466 ev->num_hndl);
2467
2468 for (i = 0; i < ev->num_hndl; i++) {
2469 struct hci_comp_blocks_info *info = &ev->handles[i];
2470 struct hci_conn *conn;
2471 __u16 handle, block_count;
2472
2473 handle = __le16_to_cpu(info->handle);
2474 block_count = __le16_to_cpu(info->blocks);
2475
2476 conn = hci_conn_hash_lookup_handle(hdev, handle);
2477 if (!conn)
2478 continue;
2479
2480 conn->sent -= block_count;
2481
2482 switch (conn->type) {
2483 case ACL_LINK:
2484 hdev->block_cnt += block_count;
2485 if (hdev->block_cnt > hdev->num_blocks)
2486 hdev->block_cnt = hdev->num_blocks;
2487 break;
2488
2489 default:
2490 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2491 break;
2492 }
2493 }
2494
2495 queue_work(hdev->workqueue, &hdev->tx_work);
2496}
2497
Marcel Holtmann04837f62006-07-03 10:02:33 +02002498static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002500 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002501 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502
2503 BT_DBG("%s status %d", hdev->name, ev->status);
2504
2505 hci_dev_lock(hdev);
2506
Marcel Holtmann04837f62006-07-03 10:02:33 +02002507 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2508 if (conn) {
2509 conn->mode = ev->mode;
2510 conn->interval = __le16_to_cpu(ev->interval);
2511
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002512 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002513 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002514 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002515 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002516 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002517 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002518
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002519 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002520 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002521 }
2522
2523 hci_dev_unlock(hdev);
2524}
2525
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2527{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002528 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2529 struct hci_conn *conn;
2530
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002531 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002532
2533 hci_dev_lock(hdev);
2534
2535 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002536 if (!conn)
2537 goto unlock;
2538
2539 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002540 hci_conn_hold(conn);
2541 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2542 hci_conn_put(conn);
2543 }
2544
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002545 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002546 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2547 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002548 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002549 u8 secure;
2550
2551 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2552 secure = 1;
2553 else
2554 secure = 0;
2555
Johan Hedberg744cf192011-11-08 20:40:14 +02002556 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002557 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002558
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002559unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002560 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561}
2562
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2564{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002565 struct hci_ev_link_key_req *ev = (void *) skb->data;
2566 struct hci_cp_link_key_reply cp;
2567 struct hci_conn *conn;
2568 struct link_key *key;
2569
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002570 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002571
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002572 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002573 return;
2574
2575 hci_dev_lock(hdev);
2576
2577 key = hci_find_link_key(hdev, &ev->bdaddr);
2578 if (!key) {
2579 BT_DBG("%s link key not found for %s", hdev->name,
2580 batostr(&ev->bdaddr));
2581 goto not_found;
2582 }
2583
2584 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2585 batostr(&ev->bdaddr));
2586
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002587 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002588 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002589 BT_DBG("%s ignoring debug key", hdev->name);
2590 goto not_found;
2591 }
2592
2593 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002594 if (conn) {
2595 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2596 conn->auth_type != 0xff &&
2597 (conn->auth_type & 0x01)) {
2598 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2599 goto not_found;
2600 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002601
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002602 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2603 conn->pending_sec_level == BT_SECURITY_HIGH) {
2604 BT_DBG("%s ignoring key unauthenticated for high \
2605 security", hdev->name);
2606 goto not_found;
2607 }
2608
2609 conn->key_type = key->type;
2610 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002611 }
2612
2613 bacpy(&cp.bdaddr, &ev->bdaddr);
2614 memcpy(cp.link_key, key->val, 16);
2615
2616 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2617
2618 hci_dev_unlock(hdev);
2619
2620 return;
2621
2622not_found:
2623 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2624 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002625}
2626
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2628{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002629 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2630 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002631 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002632
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002633 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002634
2635 hci_dev_lock(hdev);
2636
2637 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2638 if (conn) {
2639 hci_conn_hold(conn);
2640 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002641 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002642
2643 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2644 conn->key_type = ev->key_type;
2645
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002646 hci_conn_put(conn);
2647 }
2648
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002649 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002650 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002651 ev->key_type, pin_len);
2652
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002653 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654}
2655
Marcel Holtmann04837f62006-07-03 10:02:33 +02002656static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2657{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002658 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002659 struct hci_conn *conn;
2660
2661 BT_DBG("%s status %d", hdev->name, ev->status);
2662
2663 hci_dev_lock(hdev);
2664
2665 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666 if (conn && !ev->status) {
2667 struct inquiry_entry *ie;
2668
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002669 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2670 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671 ie->data.clock_offset = ev->clock_offset;
2672 ie->timestamp = jiffies;
2673 }
2674 }
2675
2676 hci_dev_unlock(hdev);
2677}
2678
Marcel Holtmanna8746412008-07-14 20:13:46 +02002679static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2680{
2681 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2682 struct hci_conn *conn;
2683
2684 BT_DBG("%s status %d", hdev->name, ev->status);
2685
2686 hci_dev_lock(hdev);
2687
2688 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2689 if (conn && !ev->status)
2690 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2691
2692 hci_dev_unlock(hdev);
2693}
2694
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002695static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2696{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002697 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002698 struct inquiry_entry *ie;
2699
2700 BT_DBG("%s", hdev->name);
2701
2702 hci_dev_lock(hdev);
2703
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002704 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2705 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002706 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2707 ie->timestamp = jiffies;
2708 }
2709
2710 hci_dev_unlock(hdev);
2711}
2712
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002713static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2714{
2715 struct inquiry_data data;
2716 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg31754052012-01-04 13:39:52 +02002717 bool name_known;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002718
2719 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2720
2721 if (!num_rsp)
2722 return;
2723
2724 hci_dev_lock(hdev);
2725
2726 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002727 struct inquiry_info_with_rssi_and_pscan_mode *info;
2728 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002729
Johan Hedberge17acd42011-03-30 23:57:16 +03002730 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002731 bacpy(&data.bdaddr, &info->bdaddr);
2732 data.pscan_rep_mode = info->pscan_rep_mode;
2733 data.pscan_period_mode = info->pscan_period_mode;
2734 data.pscan_mode = info->pscan_mode;
2735 memcpy(data.dev_class, info->dev_class, 3);
2736 data.clock_offset = info->clock_offset;
2737 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002738 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002739
2740 name_known = hci_inquiry_cache_update(hdev, &data,
2741 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002742 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002743 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002744 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002745 }
2746 } else {
2747 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2748
Johan Hedberge17acd42011-03-30 23:57:16 +03002749 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002750 bacpy(&data.bdaddr, &info->bdaddr);
2751 data.pscan_rep_mode = info->pscan_rep_mode;
2752 data.pscan_period_mode = info->pscan_period_mode;
2753 data.pscan_mode = 0x00;
2754 memcpy(data.dev_class, info->dev_class, 3);
2755 data.clock_offset = info->clock_offset;
2756 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002757 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002758 name_known = hci_inquiry_cache_update(hdev, &data,
2759 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002760 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002761 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002762 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002763 }
2764 }
2765
2766 hci_dev_unlock(hdev);
2767}
2768
2769static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2770{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002771 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2772 struct hci_conn *conn;
2773
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002774 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002775
Marcel Holtmann41a96212008-07-14 20:13:48 +02002776 hci_dev_lock(hdev);
2777
2778 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002779 if (!conn)
2780 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002781
Johan Hedbergccd556f2010-11-10 17:11:51 +02002782 if (!ev->status && ev->page == 0x01) {
2783 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002784
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002785 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2786 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002787 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002788
Johan Hedberg58a681e2012-01-16 06:47:28 +02002789 if (ev->features[0] & 0x01)
2790 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002791 }
2792
Johan Hedbergccd556f2010-11-10 17:11:51 +02002793 if (conn->state != BT_CONFIG)
2794 goto unlock;
2795
Johan Hedberg127178d2010-11-18 22:22:29 +02002796 if (!ev->status) {
2797 struct hci_cp_remote_name_req cp;
2798 memset(&cp, 0, sizeof(cp));
2799 bacpy(&cp.bdaddr, &conn->dst);
2800 cp.pscan_rep_mode = 0x02;
2801 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002802 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2803 mgmt_device_connected(hdev, &conn->dst, conn->type,
2804 conn->dst_type, NULL, 0,
2805 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002806
Johan Hedberg127178d2010-11-18 22:22:29 +02002807 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002808 conn->state = BT_CONNECTED;
2809 hci_proto_connect_cfm(conn, ev->status);
2810 hci_conn_put(conn);
2811 }
2812
2813unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002814 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002815}
2816
2817static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2818{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002819 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2820 struct hci_conn *conn;
2821
2822 BT_DBG("%s status %d", hdev->name, ev->status);
2823
2824 hci_dev_lock(hdev);
2825
2826 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002827 if (!conn) {
2828 if (ev->link_type == ESCO_LINK)
2829 goto unlock;
2830
2831 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2832 if (!conn)
2833 goto unlock;
2834
2835 conn->type = SCO_LINK;
2836 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002837
Marcel Holtmann732547f2009-04-19 19:14:14 +02002838 switch (ev->status) {
2839 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002840 conn->handle = __le16_to_cpu(ev->handle);
2841 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002842
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002843 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002844 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002845 break;
2846
Stephen Coe705e5712010-02-16 11:29:44 -05002847 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002848 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002849 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002850 case 0x1f: /* Unspecified error */
2851 if (conn->out && conn->attempt < 2) {
2852 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2853 (hdev->esco_type & EDR_ESCO_MASK);
2854 hci_setup_sync(conn, conn->link->handle);
2855 goto unlock;
2856 }
2857 /* fall through */
2858
2859 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002860 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002861 break;
2862 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002863
2864 hci_proto_connect_cfm(conn, ev->status);
2865 if (ev->status)
2866 hci_conn_del(conn);
2867
2868unlock:
2869 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002870}
2871
2872static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2873{
2874 BT_DBG("%s", hdev->name);
2875}
2876
Marcel Holtmann04837f62006-07-03 10:02:33 +02002877static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2878{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002879 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002880
2881 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002882}
2883
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002884static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2885{
2886 struct inquiry_data data;
2887 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2888 int num_rsp = *((__u8 *) skb->data);
2889
2890 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2891
2892 if (!num_rsp)
2893 return;
2894
2895 hci_dev_lock(hdev);
2896
Johan Hedberge17acd42011-03-30 23:57:16 +03002897 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg561aafb2012-01-04 13:31:59 +02002898 bool name_known;
2899
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002900 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002901 data.pscan_rep_mode = info->pscan_rep_mode;
2902 data.pscan_period_mode = info->pscan_period_mode;
2903 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002904 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002905 data.clock_offset = info->clock_offset;
2906 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002907 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002908
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002909 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002910 name_known = eir_has_data_type(info->data,
2911 sizeof(info->data),
2912 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002913 else
2914 name_known = true;
2915
Johan Hedberg31754052012-01-04 13:39:52 +02002916 name_known = hci_inquiry_cache_update(hdev, &data, name_known);
Johan Hedberg48264f02011-11-09 13:58:58 +02002917 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002918 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002919 !name_known, info->data,
2920 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002921 }
2922
2923 hci_dev_unlock(hdev);
2924}
2925
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002926static inline u8 hci_get_auth_req(struct hci_conn *conn)
2927{
2928 /* If remote requests dedicated bonding follow that lead */
2929 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2930 /* If both remote and local IO capabilities allow MITM
2931 * protection then require it, otherwise don't */
2932 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2933 return 0x02;
2934 else
2935 return 0x03;
2936 }
2937
2938 /* If remote requests no-bonding follow that lead */
2939 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002940 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002941
2942 return conn->auth_type;
2943}
2944
Marcel Holtmann04936842008-07-14 20:13:48 +02002945static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2946{
2947 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2948 struct hci_conn *conn;
2949
2950 BT_DBG("%s", hdev->name);
2951
2952 hci_dev_lock(hdev);
2953
2954 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002955 if (!conn)
2956 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002957
Johan Hedberg03b555e2011-01-04 15:40:05 +02002958 hci_conn_hold(conn);
2959
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002960 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002961 goto unlock;
2962
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002963 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02002964 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002965 struct hci_cp_io_capability_reply cp;
2966
2967 bacpy(&cp.bdaddr, &ev->bdaddr);
2968 cp.capability = conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07002969 conn->auth_type = hci_get_auth_req(conn);
2970 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002971
Johan Hedberg58a681e2012-01-16 06:47:28 +02002972 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01002973 hci_find_remote_oob_data(hdev, &conn->dst))
2974 cp.oob_data = 0x01;
2975 else
2976 cp.oob_data = 0x00;
2977
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002978 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2979 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002980 } else {
2981 struct hci_cp_io_capability_neg_reply cp;
2982
2983 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002984 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02002985
2986 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2987 sizeof(cp), &cp);
2988 }
2989
2990unlock:
2991 hci_dev_unlock(hdev);
2992}
2993
2994static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2995{
2996 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2997 struct hci_conn *conn;
2998
2999 BT_DBG("%s", hdev->name);
3000
3001 hci_dev_lock(hdev);
3002
3003 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3004 if (!conn)
3005 goto unlock;
3006
Johan Hedberg03b555e2011-01-04 15:40:05 +02003007 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003008 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003009 if (ev->oob_data)
3010 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003011
3012unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003013 hci_dev_unlock(hdev);
3014}
3015
Johan Hedberga5c29682011-02-19 12:05:57 -03003016static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3017 struct sk_buff *skb)
3018{
3019 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003020 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003021 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003022
3023 BT_DBG("%s", hdev->name);
3024
3025 hci_dev_lock(hdev);
3026
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003027 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003028 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003029
Johan Hedberg7a828902011-04-28 11:28:53 -07003030 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3031 if (!conn)
3032 goto unlock;
3033
3034 loc_mitm = (conn->auth_type & 0x01);
3035 rem_mitm = (conn->remote_auth & 0x01);
3036
3037 /* If we require MITM but the remote device can't provide that
3038 * (it has NoInputNoOutput) then reject the confirmation
3039 * request. The only exception is when we're dedicated bonding
3040 * initiators (connect_cfm_cb set) since then we always have the MITM
3041 * bit set. */
3042 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3043 BT_DBG("Rejecting request: remote device can't provide MITM");
3044 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3045 sizeof(ev->bdaddr), &ev->bdaddr);
3046 goto unlock;
3047 }
3048
3049 /* If no side requires MITM protection; auto-accept */
3050 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3051 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003052
3053 /* If we're not the initiators request authorization to
3054 * proceed from user space (mgmt_user_confirm with
3055 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003056 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003057 BT_DBG("Confirming auto-accept as acceptor");
3058 confirm_hint = 1;
3059 goto confirm;
3060 }
3061
Johan Hedberg9f616562011-04-28 11:28:54 -07003062 BT_DBG("Auto-accept of user confirmation with %ums delay",
3063 hdev->auto_accept_delay);
3064
3065 if (hdev->auto_accept_delay > 0) {
3066 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3067 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3068 goto unlock;
3069 }
3070
Johan Hedberg7a828902011-04-28 11:28:53 -07003071 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3072 sizeof(ev->bdaddr), &ev->bdaddr);
3073 goto unlock;
3074 }
3075
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003076confirm:
Johan Hedberg744cf192011-11-08 20:40:14 +02003077 mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003078 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003079
3080unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003081 hci_dev_unlock(hdev);
3082}
3083
Brian Gix1143d452011-11-23 08:28:34 -08003084static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3085 struct sk_buff *skb)
3086{
3087 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3088
3089 BT_DBG("%s", hdev->name);
3090
3091 hci_dev_lock(hdev);
3092
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003093 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08003094 mgmt_user_passkey_request(hdev, &ev->bdaddr);
3095
3096 hci_dev_unlock(hdev);
3097}
3098
Marcel Holtmann04936842008-07-14 20:13:48 +02003099static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3100{
3101 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3102 struct hci_conn *conn;
3103
3104 BT_DBG("%s", hdev->name);
3105
3106 hci_dev_lock(hdev);
3107
3108 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003109 if (!conn)
3110 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003111
Johan Hedberg2a611692011-02-19 12:06:00 -03003112 /* To avoid duplicate auth_failed events to user space we check
3113 * the HCI_CONN_AUTH_PEND flag which will be set if we
3114 * initiated the authentication. A traditional auth_complete
3115 * event gets always produced as initiator and is also mapped to
3116 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003117 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedberg744cf192011-11-08 20:40:14 +02003118 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003119
3120 hci_conn_put(conn);
3121
3122unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003123 hci_dev_unlock(hdev);
3124}
3125
Marcel Holtmann41a96212008-07-14 20:13:48 +02003126static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3127{
3128 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3129 struct inquiry_entry *ie;
3130
3131 BT_DBG("%s", hdev->name);
3132
3133 hci_dev_lock(hdev);
3134
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003135 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3136 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003137 ie->data.ssp_mode = (ev->features[0] & 0x01);
3138
3139 hci_dev_unlock(hdev);
3140}
3141
Szymon Janc2763eda2011-03-22 13:12:22 +01003142static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3143 struct sk_buff *skb)
3144{
3145 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3146 struct oob_data *data;
3147
3148 BT_DBG("%s", hdev->name);
3149
3150 hci_dev_lock(hdev);
3151
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003152 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003153 goto unlock;
3154
Szymon Janc2763eda2011-03-22 13:12:22 +01003155 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3156 if (data) {
3157 struct hci_cp_remote_oob_data_reply cp;
3158
3159 bacpy(&cp.bdaddr, &ev->bdaddr);
3160 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3161 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3162
3163 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3164 &cp);
3165 } else {
3166 struct hci_cp_remote_oob_data_neg_reply cp;
3167
3168 bacpy(&cp.bdaddr, &ev->bdaddr);
3169 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3170 &cp);
3171 }
3172
Szymon Jance1ba1f12011-04-06 13:01:59 +02003173unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003174 hci_dev_unlock(hdev);
3175}
3176
Ville Tervofcd89c02011-02-10 22:38:47 -03003177static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3178{
3179 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3180 struct hci_conn *conn;
3181
3182 BT_DBG("%s status %d", hdev->name, ev->status);
3183
3184 hci_dev_lock(hdev);
3185
3186 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003187 if (!conn) {
3188 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3189 if (!conn) {
3190 BT_ERR("No memory for new connection");
3191 hci_dev_unlock(hdev);
3192 return;
3193 }
Andre Guedes29b79882011-05-31 14:20:54 -03003194
3195 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003196 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003197
3198 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003199 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3200 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003201 hci_proto_connect_cfm(conn, ev->status);
3202 conn->state = BT_CLOSED;
3203 hci_conn_del(conn);
3204 goto unlock;
3205 }
3206
Johan Hedbergb644ba32012-01-17 21:48:47 +02003207 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3208 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3209 conn->dst_type, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003210
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003211 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003212 conn->handle = __le16_to_cpu(ev->handle);
3213 conn->state = BT_CONNECTED;
3214
3215 hci_conn_hold_device(conn);
3216 hci_conn_add_sysfs(conn);
3217
3218 hci_proto_connect_cfm(conn, ev->status);
3219
3220unlock:
3221 hci_dev_unlock(hdev);
3222}
3223
Andre Guedes9aa04c92011-05-26 16:23:51 -03003224static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3225 struct sk_buff *skb)
3226{
Andre Guedese95beb42011-09-26 20:48:35 -03003227 u8 num_reports = skb->data[0];
3228 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003229 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003230
3231 hci_dev_lock(hdev);
3232
Andre Guedese95beb42011-09-26 20:48:35 -03003233 while (num_reports--) {
3234 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003235
Andre Guedes9aa04c92011-05-26 16:23:51 -03003236 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003237
Andre Guedes3c9e9192012-01-10 18:20:50 -03003238 rssi = ev->data[ev->length];
3239 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3240 NULL, rssi, 0, ev->data, ev->length);
3241
Andre Guedese95beb42011-09-26 20:48:35 -03003242 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003243 }
3244
3245 hci_dev_unlock(hdev);
3246}
3247
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003248static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3249 struct sk_buff *skb)
3250{
3251 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3252 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003253 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003254 struct hci_conn *conn;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003255 struct link_key *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003256
3257 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3258
3259 hci_dev_lock(hdev);
3260
3261 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003262 if (conn == NULL)
3263 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003264
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003265 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3266 if (ltk == NULL)
3267 goto not_found;
3268
3269 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003270 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes726b4ff2011-07-08 18:31:45 -03003271 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003272
3273 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3274
3275 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003276
3277 return;
3278
3279not_found:
3280 neg.handle = ev->handle;
3281 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3282 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003283}
3284
Ville Tervofcd89c02011-02-10 22:38:47 -03003285static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3286{
3287 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3288
3289 skb_pull(skb, sizeof(*le_ev));
3290
3291 switch (le_ev->subevent) {
3292 case HCI_EV_LE_CONN_COMPLETE:
3293 hci_le_conn_complete_evt(hdev, skb);
3294 break;
3295
Andre Guedes9aa04c92011-05-26 16:23:51 -03003296 case HCI_EV_LE_ADVERTISING_REPORT:
3297 hci_le_adv_report_evt(hdev, skb);
3298 break;
3299
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003300 case HCI_EV_LE_LTK_REQ:
3301 hci_le_ltk_request_evt(hdev, skb);
3302 break;
3303
Ville Tervofcd89c02011-02-10 22:38:47 -03003304 default:
3305 break;
3306 }
3307}
3308
Linus Torvalds1da177e2005-04-16 15:20:36 -07003309void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3310{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003311 struct hci_event_hdr *hdr = (void *) skb->data;
3312 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003313
3314 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3315
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003316 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003317 case HCI_EV_INQUIRY_COMPLETE:
3318 hci_inquiry_complete_evt(hdev, skb);
3319 break;
3320
3321 case HCI_EV_INQUIRY_RESULT:
3322 hci_inquiry_result_evt(hdev, skb);
3323 break;
3324
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003325 case HCI_EV_CONN_COMPLETE:
3326 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003327 break;
3328
Linus Torvalds1da177e2005-04-16 15:20:36 -07003329 case HCI_EV_CONN_REQUEST:
3330 hci_conn_request_evt(hdev, skb);
3331 break;
3332
Linus Torvalds1da177e2005-04-16 15:20:36 -07003333 case HCI_EV_DISCONN_COMPLETE:
3334 hci_disconn_complete_evt(hdev, skb);
3335 break;
3336
Linus Torvalds1da177e2005-04-16 15:20:36 -07003337 case HCI_EV_AUTH_COMPLETE:
3338 hci_auth_complete_evt(hdev, skb);
3339 break;
3340
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003341 case HCI_EV_REMOTE_NAME:
3342 hci_remote_name_evt(hdev, skb);
3343 break;
3344
Linus Torvalds1da177e2005-04-16 15:20:36 -07003345 case HCI_EV_ENCRYPT_CHANGE:
3346 hci_encrypt_change_evt(hdev, skb);
3347 break;
3348
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003349 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3350 hci_change_link_key_complete_evt(hdev, skb);
3351 break;
3352
3353 case HCI_EV_REMOTE_FEATURES:
3354 hci_remote_features_evt(hdev, skb);
3355 break;
3356
3357 case HCI_EV_REMOTE_VERSION:
3358 hci_remote_version_evt(hdev, skb);
3359 break;
3360
3361 case HCI_EV_QOS_SETUP_COMPLETE:
3362 hci_qos_setup_complete_evt(hdev, skb);
3363 break;
3364
3365 case HCI_EV_CMD_COMPLETE:
3366 hci_cmd_complete_evt(hdev, skb);
3367 break;
3368
3369 case HCI_EV_CMD_STATUS:
3370 hci_cmd_status_evt(hdev, skb);
3371 break;
3372
3373 case HCI_EV_ROLE_CHANGE:
3374 hci_role_change_evt(hdev, skb);
3375 break;
3376
3377 case HCI_EV_NUM_COMP_PKTS:
3378 hci_num_comp_pkts_evt(hdev, skb);
3379 break;
3380
3381 case HCI_EV_MODE_CHANGE:
3382 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383 break;
3384
3385 case HCI_EV_PIN_CODE_REQ:
3386 hci_pin_code_request_evt(hdev, skb);
3387 break;
3388
3389 case HCI_EV_LINK_KEY_REQ:
3390 hci_link_key_request_evt(hdev, skb);
3391 break;
3392
3393 case HCI_EV_LINK_KEY_NOTIFY:
3394 hci_link_key_notify_evt(hdev, skb);
3395 break;
3396
3397 case HCI_EV_CLOCK_OFFSET:
3398 hci_clock_offset_evt(hdev, skb);
3399 break;
3400
Marcel Holtmanna8746412008-07-14 20:13:46 +02003401 case HCI_EV_PKT_TYPE_CHANGE:
3402 hci_pkt_type_change_evt(hdev, skb);
3403 break;
3404
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003405 case HCI_EV_PSCAN_REP_MODE:
3406 hci_pscan_rep_mode_evt(hdev, skb);
3407 break;
3408
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003409 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3410 hci_inquiry_result_with_rssi_evt(hdev, skb);
3411 break;
3412
3413 case HCI_EV_REMOTE_EXT_FEATURES:
3414 hci_remote_ext_features_evt(hdev, skb);
3415 break;
3416
3417 case HCI_EV_SYNC_CONN_COMPLETE:
3418 hci_sync_conn_complete_evt(hdev, skb);
3419 break;
3420
3421 case HCI_EV_SYNC_CONN_CHANGED:
3422 hci_sync_conn_changed_evt(hdev, skb);
3423 break;
3424
Marcel Holtmann04837f62006-07-03 10:02:33 +02003425 case HCI_EV_SNIFF_SUBRATE:
3426 hci_sniff_subrate_evt(hdev, skb);
3427 break;
3428
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003429 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3430 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003431 break;
3432
Marcel Holtmann04936842008-07-14 20:13:48 +02003433 case HCI_EV_IO_CAPA_REQUEST:
3434 hci_io_capa_request_evt(hdev, skb);
3435 break;
3436
Johan Hedberg03b555e2011-01-04 15:40:05 +02003437 case HCI_EV_IO_CAPA_REPLY:
3438 hci_io_capa_reply_evt(hdev, skb);
3439 break;
3440
Johan Hedberga5c29682011-02-19 12:05:57 -03003441 case HCI_EV_USER_CONFIRM_REQUEST:
3442 hci_user_confirm_request_evt(hdev, skb);
3443 break;
3444
Brian Gix1143d452011-11-23 08:28:34 -08003445 case HCI_EV_USER_PASSKEY_REQUEST:
3446 hci_user_passkey_request_evt(hdev, skb);
3447 break;
3448
Marcel Holtmann04936842008-07-14 20:13:48 +02003449 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3450 hci_simple_pair_complete_evt(hdev, skb);
3451 break;
3452
Marcel Holtmann41a96212008-07-14 20:13:48 +02003453 case HCI_EV_REMOTE_HOST_FEATURES:
3454 hci_remote_host_features_evt(hdev, skb);
3455 break;
3456
Ville Tervofcd89c02011-02-10 22:38:47 -03003457 case HCI_EV_LE_META:
3458 hci_le_meta_evt(hdev, skb);
3459 break;
3460
Szymon Janc2763eda2011-03-22 13:12:22 +01003461 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3462 hci_remote_oob_data_request_evt(hdev, skb);
3463 break;
3464
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003465 case HCI_EV_NUM_COMP_BLOCKS:
3466 hci_num_comp_blocks_evt(hdev, skb);
3467 break;
3468
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003469 default:
3470 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003471 break;
3472 }
3473
3474 kfree_skb(skb);
3475 hdev->stat.evt_rx++;
3476}
3477
3478/* Generate internal stack event */
3479void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3480{
3481 struct hci_event_hdr *hdr;
3482 struct hci_ev_stack_internal *ev;
3483 struct sk_buff *skb;
3484
3485 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3486 if (!skb)
3487 return;
3488
3489 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3490 hdr->evt = HCI_EV_STACK_INTERNAL;
3491 hdr->plen = sizeof(*ev) + dlen;
3492
3493 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3494 ev->type = type;
3495 memcpy(ev->data, data, dlen);
3496
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003497 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003498 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003499
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003500 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003501 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003502 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003503 kfree_skb(skb);
3504}
Andre Guedese6100a22011-06-30 19:20:54 -03003505
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003506module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003507MODULE_PARM_DESC(enable_le, "Enable LE support");