blob: f0b08ab734d79d17a1dd300100c262878224ae53 [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
432 hdev->ssp_mode = rp->mode;
433}
434
435static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
436{
437 __u8 status = *((__u8 *) skb->data);
438 void *sent;
439
440 BT_DBG("%s status 0x%x", hdev->name, status);
441
442 if (status)
443 return;
444
445 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
446 if (!sent)
447 return;
448
449 hdev->ssp_mode = *((__u8 *) sent);
450}
451
Johan Hedbergd5859e22011-01-25 01:19:58 +0200452static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
453{
454 if (hdev->features[6] & LMP_EXT_INQ)
455 return 2;
456
457 if (hdev->features[3] & LMP_RSSI_INQ)
458 return 1;
459
460 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
461 hdev->lmp_subver == 0x0757)
462 return 1;
463
464 if (hdev->manufacturer == 15) {
465 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
466 return 1;
467 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
468 return 1;
469 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
470 return 1;
471 }
472
473 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
474 hdev->lmp_subver == 0x1805)
475 return 1;
476
477 return 0;
478}
479
480static void hci_setup_inquiry_mode(struct hci_dev *hdev)
481{
482 u8 mode;
483
484 mode = hci_get_inquiry_mode(hdev);
485
486 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
487}
488
489static void hci_setup_event_mask(struct hci_dev *hdev)
490{
491 /* The second byte is 0xff instead of 0x9f (two reserved bits
492 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
493 * command otherwise */
494 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
495
Ville Tervo6de6c182011-05-27 11:16:21 +0300496 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
497 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200498 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300499 return;
500
501 events[4] |= 0x01; /* Flow Specification Complete */
502 events[4] |= 0x02; /* Inquiry Result with RSSI */
503 events[4] |= 0x04; /* Read Remote Extended Features Complete */
504 events[5] |= 0x08; /* Synchronous Connection Complete */
505 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200506
507 if (hdev->features[3] & LMP_RSSI_INQ)
508 events[4] |= 0x04; /* Inquiry Result with RSSI */
509
510 if (hdev->features[5] & LMP_SNIFF_SUBR)
511 events[5] |= 0x20; /* Sniff Subrating */
512
513 if (hdev->features[5] & LMP_PAUSE_ENC)
514 events[5] |= 0x80; /* Encryption Key Refresh Complete */
515
516 if (hdev->features[6] & LMP_EXT_INQ)
517 events[5] |= 0x40; /* Extended Inquiry Result */
518
519 if (hdev->features[6] & LMP_NO_FLUSH)
520 events[7] |= 0x01; /* Enhanced Flush Complete */
521
522 if (hdev->features[7] & LMP_LSTO)
523 events[6] |= 0x80; /* Link Supervision Timeout Changed */
524
525 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
526 events[6] |= 0x01; /* IO Capability Request */
527 events[6] |= 0x02; /* IO Capability Response */
528 events[6] |= 0x04; /* User Confirmation Request */
529 events[6] |= 0x08; /* User Passkey Request */
530 events[6] |= 0x10; /* Remote OOB Data Request */
531 events[6] |= 0x20; /* Simple Pairing Complete */
532 events[7] |= 0x04; /* User Passkey Notification */
533 events[7] |= 0x08; /* Keypress Notification */
534 events[7] |= 0x10; /* Remote Host Supported
535 * Features Notification */
536 }
537
538 if (hdev->features[4] & LMP_LE)
539 events[7] |= 0x20; /* LE Meta-Event */
540
541 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
542}
543
Andre Guedese6100a22011-06-30 19:20:54 -0300544static void hci_set_le_support(struct hci_dev *hdev)
545{
546 struct hci_cp_write_le_host_supported cp;
547
548 memset(&cp, 0, sizeof(cp));
549
550 if (enable_le) {
551 cp.le = 1;
552 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
553 }
554
555 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
556}
557
Johan Hedbergd5859e22011-01-25 01:19:58 +0200558static void hci_setup(struct hci_dev *hdev)
559{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200560 if (hdev->dev_type != HCI_BREDR)
561 return;
562
Johan Hedbergd5859e22011-01-25 01:19:58 +0200563 hci_setup_event_mask(hdev);
564
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200565 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200566 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
567
568 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
569 u8 mode = 0x01;
570 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
571 }
572
573 if (hdev->features[3] & LMP_RSSI_INQ)
574 hci_setup_inquiry_mode(hdev);
575
576 if (hdev->features[7] & LMP_INQ_TX_PWR)
577 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300578
579 if (hdev->features[7] & LMP_EXTFEATURES) {
580 struct hci_cp_read_local_ext_features cp;
581
582 cp.page = 0x01;
583 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
584 sizeof(cp), &cp);
585 }
Andre Guedese6100a22011-06-30 19:20:54 -0300586
587 if (hdev->features[4] & LMP_LE)
588 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200589}
590
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200591static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
592{
593 struct hci_rp_read_local_version *rp = (void *) skb->data;
594
595 BT_DBG("%s status 0x%x", hdev->name, rp->status);
596
597 if (rp->status)
598 return;
599
600 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200601 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200602 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200603 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200604 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200605
606 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
607 hdev->manufacturer,
608 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200609
610 if (test_bit(HCI_INIT, &hdev->flags))
611 hci_setup(hdev);
612}
613
614static void hci_setup_link_policy(struct hci_dev *hdev)
615{
616 u16 link_policy = 0;
617
618 if (hdev->features[0] & LMP_RSWITCH)
619 link_policy |= HCI_LP_RSWITCH;
620 if (hdev->features[0] & LMP_HOLD)
621 link_policy |= HCI_LP_HOLD;
622 if (hdev->features[0] & LMP_SNIFF)
623 link_policy |= HCI_LP_SNIFF;
624 if (hdev->features[1] & LMP_PARK)
625 link_policy |= HCI_LP_PARK;
626
627 link_policy = cpu_to_le16(link_policy);
628 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
629 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200630}
631
632static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
633{
634 struct hci_rp_read_local_commands *rp = (void *) skb->data;
635
636 BT_DBG("%s status 0x%x", hdev->name, rp->status);
637
638 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200639 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200640
641 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200642
643 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
644 hci_setup_link_policy(hdev);
645
646done:
647 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200648}
649
650static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
651{
652 struct hci_rp_read_local_features *rp = (void *) skb->data;
653
654 BT_DBG("%s status 0x%x", hdev->name, rp->status);
655
656 if (rp->status)
657 return;
658
659 memcpy(hdev->features, rp->features, 8);
660
661 /* Adjust default settings according to features
662 * supported by device. */
663
664 if (hdev->features[0] & LMP_3SLOT)
665 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
666
667 if (hdev->features[0] & LMP_5SLOT)
668 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
669
670 if (hdev->features[1] & LMP_HV2) {
671 hdev->pkt_type |= (HCI_HV2);
672 hdev->esco_type |= (ESCO_HV2);
673 }
674
675 if (hdev->features[1] & LMP_HV3) {
676 hdev->pkt_type |= (HCI_HV3);
677 hdev->esco_type |= (ESCO_HV3);
678 }
679
680 if (hdev->features[3] & LMP_ESCO)
681 hdev->esco_type |= (ESCO_EV3);
682
683 if (hdev->features[4] & LMP_EV4)
684 hdev->esco_type |= (ESCO_EV4);
685
686 if (hdev->features[4] & LMP_EV5)
687 hdev->esco_type |= (ESCO_EV5);
688
Marcel Holtmannefc76882009-02-06 09:13:37 +0100689 if (hdev->features[5] & LMP_EDR_ESCO_2M)
690 hdev->esco_type |= (ESCO_2EV3);
691
692 if (hdev->features[5] & LMP_EDR_ESCO_3M)
693 hdev->esco_type |= (ESCO_3EV3);
694
695 if (hdev->features[5] & LMP_EDR_3S_ESCO)
696 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
697
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200698 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
699 hdev->features[0], hdev->features[1],
700 hdev->features[2], hdev->features[3],
701 hdev->features[4], hdev->features[5],
702 hdev->features[6], hdev->features[7]);
703}
704
Andre Guedes971e3a42011-06-30 19:20:52 -0300705static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
706 struct sk_buff *skb)
707{
708 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
709
710 BT_DBG("%s status 0x%x", hdev->name, rp->status);
711
712 if (rp->status)
713 return;
714
Andre Guedesb5b32b62011-12-30 10:34:04 -0300715 switch (rp->page) {
716 case 0:
717 memcpy(hdev->features, rp->features, 8);
718 break;
719 case 1:
720 memcpy(hdev->host_features, rp->features, 8);
721 break;
722 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300723
724 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
725}
726
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200727static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
728 struct sk_buff *skb)
729{
730 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
731
732 BT_DBG("%s status 0x%x", hdev->name, rp->status);
733
734 if (rp->status)
735 return;
736
737 hdev->flow_ctl_mode = rp->mode;
738
739 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
740}
741
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200742static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
743{
744 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
745
746 BT_DBG("%s status 0x%x", hdev->name, rp->status);
747
748 if (rp->status)
749 return;
750
751 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
752 hdev->sco_mtu = rp->sco_mtu;
753 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
754 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
755
756 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
757 hdev->sco_mtu = 64;
758 hdev->sco_pkts = 8;
759 }
760
761 hdev->acl_cnt = hdev->acl_pkts;
762 hdev->sco_cnt = hdev->sco_pkts;
763
764 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
765 hdev->acl_mtu, hdev->acl_pkts,
766 hdev->sco_mtu, hdev->sco_pkts);
767}
768
769static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
770{
771 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
772
773 BT_DBG("%s status 0x%x", hdev->name, rp->status);
774
775 if (!rp->status)
776 bacpy(&hdev->bdaddr, &rp->bdaddr);
777
Johan Hedberg23bb5762010-12-21 23:01:27 +0200778 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
779}
780
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200781static void hci_cc_read_data_block_size(struct hci_dev *hdev,
782 struct sk_buff *skb)
783{
784 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
785
786 BT_DBG("%s status 0x%x", hdev->name, rp->status);
787
788 if (rp->status)
789 return;
790
791 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
792 hdev->block_len = __le16_to_cpu(rp->block_len);
793 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
794
795 hdev->block_cnt = hdev->num_blocks;
796
797 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
798 hdev->block_cnt, hdev->block_len);
799
800 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
801}
802
Johan Hedberg23bb5762010-12-21 23:01:27 +0200803static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
804{
805 __u8 status = *((__u8 *) skb->data);
806
807 BT_DBG("%s status 0x%x", hdev->name, status);
808
809 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200810}
811
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300812static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
813 struct sk_buff *skb)
814{
815 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
816
817 BT_DBG("%s status 0x%x", hdev->name, rp->status);
818
819 if (rp->status)
820 return;
821
822 hdev->amp_status = rp->amp_status;
823 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
824 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
825 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
826 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
827 hdev->amp_type = rp->amp_type;
828 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
829 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
830 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
831 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
832
833 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
834}
835
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200836static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
837 struct sk_buff *skb)
838{
839 __u8 status = *((__u8 *) skb->data);
840
841 BT_DBG("%s status 0x%x", hdev->name, status);
842
843 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
844}
845
Johan Hedbergd5859e22011-01-25 01:19:58 +0200846static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
847{
848 __u8 status = *((__u8 *) skb->data);
849
850 BT_DBG("%s status 0x%x", hdev->name, status);
851
852 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
853}
854
855static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
856 struct sk_buff *skb)
857{
858 __u8 status = *((__u8 *) skb->data);
859
860 BT_DBG("%s status 0x%x", hdev->name, status);
861
862 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
863}
864
865static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
866 struct sk_buff *skb)
867{
868 __u8 status = *((__u8 *) skb->data);
869
870 BT_DBG("%s status 0x%x", hdev->name, status);
871
872 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
873}
874
875static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
876{
877 __u8 status = *((__u8 *) skb->data);
878
879 BT_DBG("%s status 0x%x", hdev->name, status);
880
881 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
882}
883
Johan Hedberg980e1a52011-01-22 06:10:07 +0200884static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
885{
886 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
887 struct hci_cp_pin_code_reply *cp;
888 struct hci_conn *conn;
889
890 BT_DBG("%s status 0x%x", hdev->name, rp->status);
891
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200892 hci_dev_lock(hdev);
893
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200894 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200895 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200896
897 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200898 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200899
900 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
901 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200902 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200903
904 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
905 if (conn)
906 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200907
908unlock:
909 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200910}
911
912static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
913{
914 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
915
916 BT_DBG("%s status 0x%x", hdev->name, rp->status);
917
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200918 hci_dev_lock(hdev);
919
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200920 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200921 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200922 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200923
924 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200925}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200926
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300927static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
928 struct sk_buff *skb)
929{
930 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
931
932 BT_DBG("%s status 0x%x", hdev->name, rp->status);
933
934 if (rp->status)
935 return;
936
937 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
938 hdev->le_pkts = rp->le_max_pkt;
939
940 hdev->le_cnt = hdev->le_pkts;
941
942 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
943
944 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
945}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200946
Johan Hedberga5c29682011-02-19 12:05:57 -0300947static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
948{
949 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
950
951 BT_DBG("%s status 0x%x", hdev->name, rp->status);
952
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200953 hci_dev_lock(hdev);
954
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200955 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200956 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300957 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200958
959 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300960}
961
962static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
963 struct sk_buff *skb)
964{
965 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
966
967 BT_DBG("%s status 0x%x", hdev->name, rp->status);
968
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200969 hci_dev_lock(hdev);
970
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200971 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200972 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300973 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200974
975 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300976}
977
Brian Gix1143d452011-11-23 08:28:34 -0800978static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
979{
980 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
981
982 BT_DBG("%s status 0x%x", hdev->name, rp->status);
983
984 hci_dev_lock(hdev);
985
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200986 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800987 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr,
988 rp->status);
989
990 hci_dev_unlock(hdev);
991}
992
993static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
994 struct sk_buff *skb)
995{
996 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
997
998 BT_DBG("%s status 0x%x", hdev->name, rp->status);
999
1000 hci_dev_lock(hdev);
1001
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001002 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001003 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
1004 rp->status);
1005
1006 hci_dev_unlock(hdev);
1007}
1008
Szymon Jancc35938b2011-03-22 13:12:21 +01001009static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1010 struct sk_buff *skb)
1011{
1012 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1013
1014 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1015
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001016 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001017 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001018 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001019 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001020}
1021
Andre Guedes07f7fa52011-12-02 21:13:31 +09001022static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1023{
1024 __u8 status = *((__u8 *) skb->data);
1025
1026 BT_DBG("%s status 0x%x", hdev->name, status);
1027}
1028
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001029static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1030 struct sk_buff *skb)
1031{
1032 struct hci_cp_le_set_scan_enable *cp;
1033 __u8 status = *((__u8 *) skb->data);
1034
1035 BT_DBG("%s status 0x%x", hdev->name, status);
1036
1037 if (status)
1038 return;
1039
1040 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1041 if (!cp)
1042 return;
1043
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001044 switch (cp->enable) {
1045 case LE_SCANNING_ENABLED:
Andre Guedesd23264a2011-11-25 20:53:38 -03001046 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1047
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001048 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001049
1050 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001051 hci_adv_entries_clear(hdev);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001052 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001053 break;
1054
1055 case LE_SCANNING_DISABLED:
Andre Guedesd23264a2011-11-25 20:53:38 -03001056 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1057
Andre Guedesd0843292012-01-02 19:18:11 -03001058 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001059 break;
1060
1061 default:
1062 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1063 break;
Andre Guedes35815082011-05-26 16:23:53 -03001064 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001065}
1066
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001067static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1068{
1069 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1070
1071 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1072
1073 if (rp->status)
1074 return;
1075
1076 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1077}
1078
1079static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1080{
1081 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1082
1083 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1084
1085 if (rp->status)
1086 return;
1087
1088 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1089}
1090
Andre Guedesf9b49302011-06-30 19:20:53 -03001091static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1092 struct sk_buff *skb)
1093{
1094 struct hci_cp_read_local_ext_features cp;
1095 __u8 status = *((__u8 *) skb->data);
1096
1097 BT_DBG("%s status 0x%x", hdev->name, status);
1098
1099 if (status)
1100 return;
1101
1102 cp.page = 0x01;
1103 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1104}
1105
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001106static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1107{
1108 BT_DBG("%s status 0x%x", hdev->name, status);
1109
1110 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001111 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001112 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001113 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001114 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001115 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001116 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001117 return;
1118 }
1119
Andre Guedes89352e72011-11-04 14:16:53 -03001120 set_bit(HCI_INQUIRY, &hdev->flags);
1121
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001122 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001123 hci_discovery_set_state(hdev, DISCOVERY_INQUIRY);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001124 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001125}
1126
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1128{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001129 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001132 BT_DBG("%s status 0x%x", hdev->name, status);
1133
1134 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 if (!cp)
1136 return;
1137
1138 hci_dev_lock(hdev);
1139
1140 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1141
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001142 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143
1144 if (status) {
1145 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001146 if (status != 0x0c || conn->attempt > 2) {
1147 conn->state = BT_CLOSED;
1148 hci_proto_connect_cfm(conn, status);
1149 hci_conn_del(conn);
1150 } else
1151 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 }
1153 } else {
1154 if (!conn) {
1155 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1156 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001157 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 conn->link_mode |= HCI_LM_MASTER;
1159 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001160 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 }
1162 }
1163
1164 hci_dev_unlock(hdev);
1165}
1166
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001167static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001169 struct hci_cp_add_sco *cp;
1170 struct hci_conn *acl, *sco;
1171 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001173 BT_DBG("%s status 0x%x", hdev->name, status);
1174
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001175 if (!status)
1176 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001178 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1179 if (!cp)
1180 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001182 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001184 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001185
1186 hci_dev_lock(hdev);
1187
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001188 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001189 if (acl) {
1190 sco = acl->link;
1191 if (sco) {
1192 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001193
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001194 hci_proto_connect_cfm(sco, status);
1195 hci_conn_del(sco);
1196 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001197 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001198
1199 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200}
1201
Marcel Holtmannf8558552008-07-14 20:13:49 +02001202static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1203{
1204 struct hci_cp_auth_requested *cp;
1205 struct hci_conn *conn;
1206
1207 BT_DBG("%s status 0x%x", hdev->name, status);
1208
1209 if (!status)
1210 return;
1211
1212 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1213 if (!cp)
1214 return;
1215
1216 hci_dev_lock(hdev);
1217
1218 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1219 if (conn) {
1220 if (conn->state == BT_CONFIG) {
1221 hci_proto_connect_cfm(conn, status);
1222 hci_conn_put(conn);
1223 }
1224 }
1225
1226 hci_dev_unlock(hdev);
1227}
1228
1229static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1230{
1231 struct hci_cp_set_conn_encrypt *cp;
1232 struct hci_conn *conn;
1233
1234 BT_DBG("%s status 0x%x", hdev->name, status);
1235
1236 if (!status)
1237 return;
1238
1239 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1240 if (!cp)
1241 return;
1242
1243 hci_dev_lock(hdev);
1244
1245 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1246 if (conn) {
1247 if (conn->state == BT_CONFIG) {
1248 hci_proto_connect_cfm(conn, status);
1249 hci_conn_put(conn);
1250 }
1251 }
1252
1253 hci_dev_unlock(hdev);
1254}
1255
Johan Hedberg127178d2010-11-18 22:22:29 +02001256static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001257 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001258{
Johan Hedberg392599b2010-11-18 22:22:28 +02001259 if (conn->state != BT_CONFIG || !conn->out)
1260 return 0;
1261
Johan Hedberg765c2a92011-01-19 12:06:52 +05301262 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001263 return 0;
1264
1265 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001266 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedberg392599b2010-11-18 22:22:28 +02001267 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001268 conn->pending_sec_level != BT_SECURITY_HIGH &&
1269 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001270 return 0;
1271
Johan Hedberg392599b2010-11-18 22:22:28 +02001272 return 1;
1273}
1274
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001275static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1276{
1277 struct hci_cp_remote_name_req cp;
1278
1279 memset(&cp, 0, sizeof(cp));
1280
1281 bacpy(&cp.bdaddr, &e->data.bdaddr);
1282 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1283 cp.pscan_mode = e->data.pscan_mode;
1284 cp.clock_offset = e->data.clock_offset;
1285
1286 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1287}
1288
Johan Hedbergb644ba32012-01-17 21:48:47 +02001289static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001290{
1291 struct discovery_state *discov = &hdev->discovery;
1292 struct inquiry_entry *e;
1293
Johan Hedbergb644ba32012-01-17 21:48:47 +02001294 if (list_empty(&discov->resolve))
1295 return false;
1296
1297 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1298 if (hci_resolve_name(hdev, e) == 0) {
1299 e->name_state = NAME_PENDING;
1300 return true;
1301 }
1302
1303 return false;
1304}
1305
1306static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1307 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1308{
1309 struct discovery_state *discov = &hdev->discovery;
1310 struct inquiry_entry *e;
1311
1312 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1313 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
1314 name, name_len, conn->dev_class);
1315
1316 if (discov->state == DISCOVERY_STOPPED)
1317 return;
1318
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001319 if (discov->state == DISCOVERY_STOPPING)
1320 goto discov_complete;
1321
1322 if (discov->state != DISCOVERY_RESOLVING)
1323 return;
1324
1325 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1326 if (e) {
1327 e->name_state = NAME_KNOWN;
1328 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001329 if (name)
1330 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1331 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001332 }
1333
Johan Hedbergb644ba32012-01-17 21:48:47 +02001334 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001335 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001336
1337discov_complete:
1338 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1339}
1340
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001341static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1342{
Johan Hedberg127178d2010-11-18 22:22:29 +02001343 struct hci_cp_remote_name_req *cp;
1344 struct hci_conn *conn;
1345
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001346 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001347
1348 /* If successful wait for the name req complete event before
1349 * checking for the need to do authentication */
1350 if (!status)
1351 return;
1352
1353 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1354 if (!cp)
1355 return;
1356
1357 hci_dev_lock(hdev);
1358
1359 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001360
1361 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1362 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1363
Johan Hedberg79c6c702011-04-28 11:28:55 -07001364 if (!conn)
1365 goto unlock;
1366
1367 if (!hci_outgoing_auth_needed(hdev, conn))
1368 goto unlock;
1369
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001370 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001371 struct hci_cp_auth_requested cp;
1372 cp.handle = __cpu_to_le16(conn->handle);
1373 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1374 }
1375
Johan Hedberg79c6c702011-04-28 11:28:55 -07001376unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001377 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001378}
1379
Marcel Holtmann769be972008-07-14 20:13:49 +02001380static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1381{
1382 struct hci_cp_read_remote_features *cp;
1383 struct hci_conn *conn;
1384
1385 BT_DBG("%s status 0x%x", hdev->name, status);
1386
1387 if (!status)
1388 return;
1389
1390 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1391 if (!cp)
1392 return;
1393
1394 hci_dev_lock(hdev);
1395
1396 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1397 if (conn) {
1398 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001399 hci_proto_connect_cfm(conn, status);
1400 hci_conn_put(conn);
1401 }
1402 }
1403
1404 hci_dev_unlock(hdev);
1405}
1406
1407static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1408{
1409 struct hci_cp_read_remote_ext_features *cp;
1410 struct hci_conn *conn;
1411
1412 BT_DBG("%s status 0x%x", hdev->name, status);
1413
1414 if (!status)
1415 return;
1416
1417 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1418 if (!cp)
1419 return;
1420
1421 hci_dev_lock(hdev);
1422
1423 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1424 if (conn) {
1425 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001426 hci_proto_connect_cfm(conn, status);
1427 hci_conn_put(conn);
1428 }
1429 }
1430
1431 hci_dev_unlock(hdev);
1432}
1433
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001434static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1435{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001436 struct hci_cp_setup_sync_conn *cp;
1437 struct hci_conn *acl, *sco;
1438 __u16 handle;
1439
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001440 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001441
1442 if (!status)
1443 return;
1444
1445 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1446 if (!cp)
1447 return;
1448
1449 handle = __le16_to_cpu(cp->handle);
1450
1451 BT_DBG("%s handle %d", hdev->name, handle);
1452
1453 hci_dev_lock(hdev);
1454
1455 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001456 if (acl) {
1457 sco = acl->link;
1458 if (sco) {
1459 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001460
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001461 hci_proto_connect_cfm(sco, status);
1462 hci_conn_del(sco);
1463 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001464 }
1465
1466 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001467}
1468
1469static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1470{
1471 struct hci_cp_sniff_mode *cp;
1472 struct hci_conn *conn;
1473
1474 BT_DBG("%s status 0x%x", hdev->name, status);
1475
1476 if (!status)
1477 return;
1478
1479 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1480 if (!cp)
1481 return;
1482
1483 hci_dev_lock(hdev);
1484
1485 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001486 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001487 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001488
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001489 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001490 hci_sco_setup(conn, status);
1491 }
1492
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001493 hci_dev_unlock(hdev);
1494}
1495
1496static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1497{
1498 struct hci_cp_exit_sniff_mode *cp;
1499 struct hci_conn *conn;
1500
1501 BT_DBG("%s status 0x%x", hdev->name, status);
1502
1503 if (!status)
1504 return;
1505
1506 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1507 if (!cp)
1508 return;
1509
1510 hci_dev_lock(hdev);
1511
1512 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001513 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001514 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001515
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001516 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001517 hci_sco_setup(conn, status);
1518 }
1519
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001520 hci_dev_unlock(hdev);
1521}
1522
Ville Tervofcd89c02011-02-10 22:38:47 -03001523static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1524{
1525 struct hci_cp_le_create_conn *cp;
1526 struct hci_conn *conn;
1527
1528 BT_DBG("%s status 0x%x", hdev->name, status);
1529
1530 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1531 if (!cp)
1532 return;
1533
1534 hci_dev_lock(hdev);
1535
1536 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1537
1538 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1539 conn);
1540
1541 if (status) {
1542 if (conn && conn->state == BT_CONNECT) {
1543 conn->state = BT_CLOSED;
1544 hci_proto_connect_cfm(conn, status);
1545 hci_conn_del(conn);
1546 }
1547 } else {
1548 if (!conn) {
1549 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001550 if (conn) {
1551 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001552 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001553 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001554 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001555 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001556 }
1557 }
1558
1559 hci_dev_unlock(hdev);
1560}
1561
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001562static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1563{
1564 BT_DBG("%s status 0x%x", hdev->name, status);
1565}
1566
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001567static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1568{
1569 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001570 struct discovery_state *discov = &hdev->discovery;
1571 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001572
1573 BT_DBG("%s status %d", hdev->name, status);
1574
Johan Hedberg23bb5762010-12-21 23:01:27 +02001575 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001576
1577 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001578
1579 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1580 return;
1581
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001582 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001583 return;
1584
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001585 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001586
1587 if (discov->state != DISCOVERY_INQUIRY)
1588 goto unlock;
1589
1590 if (list_empty(&discov->resolve)) {
1591 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1592 goto unlock;
1593 }
1594
1595 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1596 if (e && hci_resolve_name(hdev, e) == 0) {
1597 e->name_state = NAME_PENDING;
1598 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1599 } else {
1600 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1601 }
1602
1603unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001604 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001605}
1606
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1608{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001609 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001610 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 int num_rsp = *((__u8 *) skb->data);
1612
1613 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1614
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001615 if (!num_rsp)
1616 return;
1617
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001619
Johan Hedberge17acd42011-03-30 23:57:16 +03001620 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg31754052012-01-04 13:39:52 +02001621 bool name_known;
1622
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 bacpy(&data.bdaddr, &info->bdaddr);
1624 data.pscan_rep_mode = info->pscan_rep_mode;
1625 data.pscan_period_mode = info->pscan_period_mode;
1626 data.pscan_mode = info->pscan_mode;
1627 memcpy(data.dev_class, info->dev_class, 3);
1628 data.clock_offset = info->clock_offset;
1629 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001630 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001631
1632 name_known = hci_inquiry_cache_update(hdev, &data, false);
Johan Hedberg48264f02011-11-09 13:58:58 +02001633 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Andre Guedes7d262f82012-01-10 18:20:49 -03001634 info->dev_class, 0, !name_known,
1635 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001637
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 hci_dev_unlock(hdev);
1639}
1640
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001641static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001643 struct hci_ev_conn_complete *ev = (void *) skb->data;
1644 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001646 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001647
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001649
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001650 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001651 if (!conn) {
1652 if (ev->link_type != SCO_LINK)
1653 goto unlock;
1654
1655 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1656 if (!conn)
1657 goto unlock;
1658
1659 conn->type = SCO_LINK;
1660 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001661
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001662 if (!ev->status) {
1663 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001664
1665 if (conn->type == ACL_LINK) {
1666 conn->state = BT_CONFIG;
1667 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001668 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001669 } else
1670 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001671
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001672 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001673 hci_conn_add_sysfs(conn);
1674
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001675 if (test_bit(HCI_AUTH, &hdev->flags))
1676 conn->link_mode |= HCI_LM_AUTH;
1677
1678 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1679 conn->link_mode |= HCI_LM_ENCRYPT;
1680
1681 /* Get remote features */
1682 if (conn->type == ACL_LINK) {
1683 struct hci_cp_read_remote_features cp;
1684 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001685 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1686 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001687 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001688
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001689 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001690 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001691 struct hci_cp_change_conn_ptype cp;
1692 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001693 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1694 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1695 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001696 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001697 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001698 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001699 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001700 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001701 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001702 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001703
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001704 if (conn->type == ACL_LINK)
1705 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001706
Marcel Holtmann769be972008-07-14 20:13:49 +02001707 if (ev->status) {
1708 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001709 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001710 } else if (ev->link_type != ACL_LINK)
1711 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001712
1713unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001715
1716 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717}
1718
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1720{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001721 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 int mask = hdev->link_mode;
1723
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001724 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1725 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726
1727 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1728
Szymon Janc138d22e2011-02-17 16:44:23 +01001729 if ((mask & HCI_LM_ACCEPT) &&
1730 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001732 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734
1735 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001736
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001737 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1738 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001739 memcpy(ie->data.dev_class, ev->dev_class, 3);
1740
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1742 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001743 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1744 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001745 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746 hci_dev_unlock(hdev);
1747 return;
1748 }
1749 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001750
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751 memcpy(conn->dev_class, ev->dev_class, 3);
1752 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001753
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 hci_dev_unlock(hdev);
1755
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001756 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1757 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001759 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001761 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1762 cp.role = 0x00; /* Become master */
1763 else
1764 cp.role = 0x01; /* Remain slave */
1765
1766 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1767 sizeof(cp), &cp);
1768 } else {
1769 struct hci_cp_accept_sync_conn_req cp;
1770
1771 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001772 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001773
1774 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1775 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1776 cp.max_latency = cpu_to_le16(0xffff);
1777 cp.content_format = cpu_to_le16(hdev->voice_setting);
1778 cp.retrans_effort = 0xff;
1779
1780 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1781 sizeof(cp), &cp);
1782 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783 } else {
1784 /* Connection rejected */
1785 struct hci_cp_reject_conn_req cp;
1786
1787 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001788 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001789 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 }
1791}
1792
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1794{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001795 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001796 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797
1798 BT_DBG("%s status %d", hdev->name, ev->status);
1799
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 hci_dev_lock(hdev);
1801
Marcel Holtmann04837f62006-07-03 10:02:33 +02001802 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001803 if (!conn)
1804 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001805
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001806 if (ev->status == 0)
1807 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808
Johan Hedbergb644ba32012-01-17 21:48:47 +02001809 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1810 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001811 if (ev->status != 0)
1812 mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
1813 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001814 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001815 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001816 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001817
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001818 if (ev->status == 0) {
1819 hci_proto_disconn_cfm(conn, ev->reason);
1820 hci_conn_del(conn);
1821 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001822
1823unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 hci_dev_unlock(hdev);
1825}
1826
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001827static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1828{
1829 struct hci_ev_auth_complete *ev = (void *) skb->data;
1830 struct hci_conn *conn;
1831
1832 BT_DBG("%s status %d", hdev->name, ev->status);
1833
1834 hci_dev_lock(hdev);
1835
1836 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001837 if (!conn)
1838 goto unlock;
1839
1840 if (!ev->status) {
1841 if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) &&
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001842 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001843 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001844 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001845 conn->link_mode |= HCI_LM_AUTH;
1846 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001847 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001848 } else {
Johan Hedberg744cf192011-11-08 20:40:14 +02001849 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001850 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001851
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001852 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1853 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001854
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001855 if (conn->state == BT_CONFIG) {
1856 if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) {
1857 struct hci_cp_set_conn_encrypt cp;
1858 cp.handle = ev->handle;
1859 cp.encrypt = 0x01;
1860 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1861 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001862 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001863 conn->state = BT_CONNECTED;
1864 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001865 hci_conn_put(conn);
1866 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001867 } else {
1868 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001869
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001870 hci_conn_hold(conn);
1871 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1872 hci_conn_put(conn);
1873 }
1874
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001875 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001876 if (!ev->status) {
1877 struct hci_cp_set_conn_encrypt cp;
1878 cp.handle = ev->handle;
1879 cp.encrypt = 0x01;
1880 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1881 &cp);
1882 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001883 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001884 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001885 }
1886 }
1887
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001888unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001889 hci_dev_unlock(hdev);
1890}
1891
1892static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1893{
Johan Hedberg127178d2010-11-18 22:22:29 +02001894 struct hci_ev_remote_name *ev = (void *) skb->data;
1895 struct hci_conn *conn;
1896
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001897 BT_DBG("%s", hdev->name);
1898
1899 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001900
1901 hci_dev_lock(hdev);
1902
1903 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001904
1905 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1906 goto check_auth;
1907
1908 if (ev->status == 0)
1909 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1910 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1911 else
1912 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1913
1914check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001915 if (!conn)
1916 goto unlock;
1917
1918 if (!hci_outgoing_auth_needed(hdev, conn))
1919 goto unlock;
1920
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001921 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001922 struct hci_cp_auth_requested cp;
1923 cp.handle = __cpu_to_le16(conn->handle);
1924 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1925 }
1926
Johan Hedberg79c6c702011-04-28 11:28:55 -07001927unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001928 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001929}
1930
1931static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1932{
1933 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1934 struct hci_conn *conn;
1935
1936 BT_DBG("%s status %d", hdev->name, ev->status);
1937
1938 hci_dev_lock(hdev);
1939
1940 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1941 if (conn) {
1942 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001943 if (ev->encrypt) {
1944 /* Encryption implies authentication */
1945 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001946 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001947 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001948 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001949 conn->link_mode &= ~HCI_LM_ENCRYPT;
1950 }
1951
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001952 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001953
Marcel Holtmannf8558552008-07-14 20:13:49 +02001954 if (conn->state == BT_CONFIG) {
1955 if (!ev->status)
1956 conn->state = BT_CONNECTED;
1957
1958 hci_proto_connect_cfm(conn, ev->status);
1959 hci_conn_put(conn);
1960 } else
1961 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001962 }
1963
1964 hci_dev_unlock(hdev);
1965}
1966
1967static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1968{
1969 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1970 struct hci_conn *conn;
1971
1972 BT_DBG("%s status %d", hdev->name, ev->status);
1973
1974 hci_dev_lock(hdev);
1975
1976 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1977 if (conn) {
1978 if (!ev->status)
1979 conn->link_mode |= HCI_LM_SECURE;
1980
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001981 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001982
1983 hci_key_change_cfm(conn, ev->status);
1984 }
1985
1986 hci_dev_unlock(hdev);
1987}
1988
1989static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1990{
1991 struct hci_ev_remote_features *ev = (void *) skb->data;
1992 struct hci_conn *conn;
1993
1994 BT_DBG("%s status %d", hdev->name, ev->status);
1995
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001996 hci_dev_lock(hdev);
1997
1998 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001999 if (!conn)
2000 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002001
Johan Hedbergccd556f2010-11-10 17:11:51 +02002002 if (!ev->status)
2003 memcpy(conn->features, ev->features, 8);
2004
2005 if (conn->state != BT_CONFIG)
2006 goto unlock;
2007
2008 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2009 struct hci_cp_read_remote_ext_features cp;
2010 cp.handle = ev->handle;
2011 cp.page = 0x01;
2012 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002013 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002014 goto unlock;
2015 }
2016
Johan Hedberg127178d2010-11-18 22:22:29 +02002017 if (!ev->status) {
2018 struct hci_cp_remote_name_req cp;
2019 memset(&cp, 0, sizeof(cp));
2020 bacpy(&cp.bdaddr, &conn->dst);
2021 cp.pscan_rep_mode = 0x02;
2022 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002023 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2024 mgmt_device_connected(hdev, &conn->dst, conn->type,
2025 conn->dst_type, NULL, 0,
2026 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002027
Johan Hedberg127178d2010-11-18 22:22:29 +02002028 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002029 conn->state = BT_CONNECTED;
2030 hci_proto_connect_cfm(conn, ev->status);
2031 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002032 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002033
Johan Hedbergccd556f2010-11-10 17:11:51 +02002034unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002035 hci_dev_unlock(hdev);
2036}
2037
2038static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2039{
2040 BT_DBG("%s", hdev->name);
2041}
2042
2043static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2044{
2045 BT_DBG("%s", hdev->name);
2046}
2047
2048static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2049{
2050 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2051 __u16 opcode;
2052
2053 skb_pull(skb, sizeof(*ev));
2054
2055 opcode = __le16_to_cpu(ev->opcode);
2056
2057 switch (opcode) {
2058 case HCI_OP_INQUIRY_CANCEL:
2059 hci_cc_inquiry_cancel(hdev, skb);
2060 break;
2061
2062 case HCI_OP_EXIT_PERIODIC_INQ:
2063 hci_cc_exit_periodic_inq(hdev, skb);
2064 break;
2065
2066 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2067 hci_cc_remote_name_req_cancel(hdev, skb);
2068 break;
2069
2070 case HCI_OP_ROLE_DISCOVERY:
2071 hci_cc_role_discovery(hdev, skb);
2072 break;
2073
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002074 case HCI_OP_READ_LINK_POLICY:
2075 hci_cc_read_link_policy(hdev, skb);
2076 break;
2077
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002078 case HCI_OP_WRITE_LINK_POLICY:
2079 hci_cc_write_link_policy(hdev, skb);
2080 break;
2081
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002082 case HCI_OP_READ_DEF_LINK_POLICY:
2083 hci_cc_read_def_link_policy(hdev, skb);
2084 break;
2085
2086 case HCI_OP_WRITE_DEF_LINK_POLICY:
2087 hci_cc_write_def_link_policy(hdev, skb);
2088 break;
2089
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002090 case HCI_OP_RESET:
2091 hci_cc_reset(hdev, skb);
2092 break;
2093
2094 case HCI_OP_WRITE_LOCAL_NAME:
2095 hci_cc_write_local_name(hdev, skb);
2096 break;
2097
2098 case HCI_OP_READ_LOCAL_NAME:
2099 hci_cc_read_local_name(hdev, skb);
2100 break;
2101
2102 case HCI_OP_WRITE_AUTH_ENABLE:
2103 hci_cc_write_auth_enable(hdev, skb);
2104 break;
2105
2106 case HCI_OP_WRITE_ENCRYPT_MODE:
2107 hci_cc_write_encrypt_mode(hdev, skb);
2108 break;
2109
2110 case HCI_OP_WRITE_SCAN_ENABLE:
2111 hci_cc_write_scan_enable(hdev, skb);
2112 break;
2113
2114 case HCI_OP_READ_CLASS_OF_DEV:
2115 hci_cc_read_class_of_dev(hdev, skb);
2116 break;
2117
2118 case HCI_OP_WRITE_CLASS_OF_DEV:
2119 hci_cc_write_class_of_dev(hdev, skb);
2120 break;
2121
2122 case HCI_OP_READ_VOICE_SETTING:
2123 hci_cc_read_voice_setting(hdev, skb);
2124 break;
2125
2126 case HCI_OP_WRITE_VOICE_SETTING:
2127 hci_cc_write_voice_setting(hdev, skb);
2128 break;
2129
2130 case HCI_OP_HOST_BUFFER_SIZE:
2131 hci_cc_host_buffer_size(hdev, skb);
2132 break;
2133
Marcel Holtmann333140b2008-07-14 20:13:48 +02002134 case HCI_OP_READ_SSP_MODE:
2135 hci_cc_read_ssp_mode(hdev, skb);
2136 break;
2137
2138 case HCI_OP_WRITE_SSP_MODE:
2139 hci_cc_write_ssp_mode(hdev, skb);
2140 break;
2141
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002142 case HCI_OP_READ_LOCAL_VERSION:
2143 hci_cc_read_local_version(hdev, skb);
2144 break;
2145
2146 case HCI_OP_READ_LOCAL_COMMANDS:
2147 hci_cc_read_local_commands(hdev, skb);
2148 break;
2149
2150 case HCI_OP_READ_LOCAL_FEATURES:
2151 hci_cc_read_local_features(hdev, skb);
2152 break;
2153
Andre Guedes971e3a42011-06-30 19:20:52 -03002154 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2155 hci_cc_read_local_ext_features(hdev, skb);
2156 break;
2157
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002158 case HCI_OP_READ_BUFFER_SIZE:
2159 hci_cc_read_buffer_size(hdev, skb);
2160 break;
2161
2162 case HCI_OP_READ_BD_ADDR:
2163 hci_cc_read_bd_addr(hdev, skb);
2164 break;
2165
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002166 case HCI_OP_READ_DATA_BLOCK_SIZE:
2167 hci_cc_read_data_block_size(hdev, skb);
2168 break;
2169
Johan Hedberg23bb5762010-12-21 23:01:27 +02002170 case HCI_OP_WRITE_CA_TIMEOUT:
2171 hci_cc_write_ca_timeout(hdev, skb);
2172 break;
2173
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002174 case HCI_OP_READ_FLOW_CONTROL_MODE:
2175 hci_cc_read_flow_control_mode(hdev, skb);
2176 break;
2177
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002178 case HCI_OP_READ_LOCAL_AMP_INFO:
2179 hci_cc_read_local_amp_info(hdev, skb);
2180 break;
2181
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002182 case HCI_OP_DELETE_STORED_LINK_KEY:
2183 hci_cc_delete_stored_link_key(hdev, skb);
2184 break;
2185
Johan Hedbergd5859e22011-01-25 01:19:58 +02002186 case HCI_OP_SET_EVENT_MASK:
2187 hci_cc_set_event_mask(hdev, skb);
2188 break;
2189
2190 case HCI_OP_WRITE_INQUIRY_MODE:
2191 hci_cc_write_inquiry_mode(hdev, skb);
2192 break;
2193
2194 case HCI_OP_READ_INQ_RSP_TX_POWER:
2195 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2196 break;
2197
2198 case HCI_OP_SET_EVENT_FLT:
2199 hci_cc_set_event_flt(hdev, skb);
2200 break;
2201
Johan Hedberg980e1a52011-01-22 06:10:07 +02002202 case HCI_OP_PIN_CODE_REPLY:
2203 hci_cc_pin_code_reply(hdev, skb);
2204 break;
2205
2206 case HCI_OP_PIN_CODE_NEG_REPLY:
2207 hci_cc_pin_code_neg_reply(hdev, skb);
2208 break;
2209
Szymon Jancc35938b2011-03-22 13:12:21 +01002210 case HCI_OP_READ_LOCAL_OOB_DATA:
2211 hci_cc_read_local_oob_data_reply(hdev, skb);
2212 break;
2213
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002214 case HCI_OP_LE_READ_BUFFER_SIZE:
2215 hci_cc_le_read_buffer_size(hdev, skb);
2216 break;
2217
Johan Hedberga5c29682011-02-19 12:05:57 -03002218 case HCI_OP_USER_CONFIRM_REPLY:
2219 hci_cc_user_confirm_reply(hdev, skb);
2220 break;
2221
2222 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2223 hci_cc_user_confirm_neg_reply(hdev, skb);
2224 break;
2225
Brian Gix1143d452011-11-23 08:28:34 -08002226 case HCI_OP_USER_PASSKEY_REPLY:
2227 hci_cc_user_passkey_reply(hdev, skb);
2228 break;
2229
2230 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2231 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002232
2233 case HCI_OP_LE_SET_SCAN_PARAM:
2234 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002235 break;
2236
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002237 case HCI_OP_LE_SET_SCAN_ENABLE:
2238 hci_cc_le_set_scan_enable(hdev, skb);
2239 break;
2240
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002241 case HCI_OP_LE_LTK_REPLY:
2242 hci_cc_le_ltk_reply(hdev, skb);
2243 break;
2244
2245 case HCI_OP_LE_LTK_NEG_REPLY:
2246 hci_cc_le_ltk_neg_reply(hdev, skb);
2247 break;
2248
Andre Guedesf9b49302011-06-30 19:20:53 -03002249 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2250 hci_cc_write_le_host_supported(hdev, skb);
2251 break;
2252
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002253 default:
2254 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2255 break;
2256 }
2257
Ville Tervo6bd32322011-02-16 16:32:41 +02002258 if (ev->opcode != HCI_OP_NOP)
2259 del_timer(&hdev->cmd_timer);
2260
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002261 if (ev->ncmd) {
2262 atomic_set(&hdev->cmd_cnt, 1);
2263 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002264 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002265 }
2266}
2267
2268static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2269{
2270 struct hci_ev_cmd_status *ev = (void *) skb->data;
2271 __u16 opcode;
2272
2273 skb_pull(skb, sizeof(*ev));
2274
2275 opcode = __le16_to_cpu(ev->opcode);
2276
2277 switch (opcode) {
2278 case HCI_OP_INQUIRY:
2279 hci_cs_inquiry(hdev, ev->status);
2280 break;
2281
2282 case HCI_OP_CREATE_CONN:
2283 hci_cs_create_conn(hdev, ev->status);
2284 break;
2285
2286 case HCI_OP_ADD_SCO:
2287 hci_cs_add_sco(hdev, ev->status);
2288 break;
2289
Marcel Holtmannf8558552008-07-14 20:13:49 +02002290 case HCI_OP_AUTH_REQUESTED:
2291 hci_cs_auth_requested(hdev, ev->status);
2292 break;
2293
2294 case HCI_OP_SET_CONN_ENCRYPT:
2295 hci_cs_set_conn_encrypt(hdev, ev->status);
2296 break;
2297
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002298 case HCI_OP_REMOTE_NAME_REQ:
2299 hci_cs_remote_name_req(hdev, ev->status);
2300 break;
2301
Marcel Holtmann769be972008-07-14 20:13:49 +02002302 case HCI_OP_READ_REMOTE_FEATURES:
2303 hci_cs_read_remote_features(hdev, ev->status);
2304 break;
2305
2306 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2307 hci_cs_read_remote_ext_features(hdev, ev->status);
2308 break;
2309
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002310 case HCI_OP_SETUP_SYNC_CONN:
2311 hci_cs_setup_sync_conn(hdev, ev->status);
2312 break;
2313
2314 case HCI_OP_SNIFF_MODE:
2315 hci_cs_sniff_mode(hdev, ev->status);
2316 break;
2317
2318 case HCI_OP_EXIT_SNIFF_MODE:
2319 hci_cs_exit_sniff_mode(hdev, ev->status);
2320 break;
2321
Johan Hedberg8962ee72011-01-20 12:40:27 +02002322 case HCI_OP_DISCONNECT:
2323 if (ev->status != 0)
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002324 mgmt_disconnect_failed(hdev, NULL, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002325 break;
2326
Ville Tervofcd89c02011-02-10 22:38:47 -03002327 case HCI_OP_LE_CREATE_CONN:
2328 hci_cs_le_create_conn(hdev, ev->status);
2329 break;
2330
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002331 case HCI_OP_LE_START_ENC:
2332 hci_cs_le_start_enc(hdev, ev->status);
2333 break;
2334
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002335 default:
2336 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2337 break;
2338 }
2339
Ville Tervo6bd32322011-02-16 16:32:41 +02002340 if (ev->opcode != HCI_OP_NOP)
2341 del_timer(&hdev->cmd_timer);
2342
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002343 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002344 atomic_set(&hdev->cmd_cnt, 1);
2345 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002346 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002347 }
2348}
2349
2350static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2351{
2352 struct hci_ev_role_change *ev = (void *) skb->data;
2353 struct hci_conn *conn;
2354
2355 BT_DBG("%s status %d", hdev->name, ev->status);
2356
2357 hci_dev_lock(hdev);
2358
2359 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2360 if (conn) {
2361 if (!ev->status) {
2362 if (ev->role)
2363 conn->link_mode &= ~HCI_LM_MASTER;
2364 else
2365 conn->link_mode |= HCI_LM_MASTER;
2366 }
2367
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002368 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002369
2370 hci_role_switch_cfm(conn, ev->status, ev->role);
2371 }
2372
2373 hci_dev_unlock(hdev);
2374}
2375
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2377{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002378 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379 int i;
2380
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002381 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2382 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2383 return;
2384 }
2385
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002386 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2387 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002388 BT_DBG("%s bad parameters", hdev->name);
2389 return;
2390 }
2391
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002392 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2393
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002394 for (i = 0; i < ev->num_hndl; i++) {
2395 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002396 struct hci_conn *conn;
2397 __u16 handle, count;
2398
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002399 handle = __le16_to_cpu(info->handle);
2400 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401
2402 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002403 if (!conn)
2404 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002406 conn->sent -= count;
2407
2408 switch (conn->type) {
2409 case ACL_LINK:
2410 hdev->acl_cnt += count;
2411 if (hdev->acl_cnt > hdev->acl_pkts)
2412 hdev->acl_cnt = hdev->acl_pkts;
2413 break;
2414
2415 case LE_LINK:
2416 if (hdev->le_pkts) {
2417 hdev->le_cnt += count;
2418 if (hdev->le_cnt > hdev->le_pkts)
2419 hdev->le_cnt = hdev->le_pkts;
2420 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002421 hdev->acl_cnt += count;
2422 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002423 hdev->acl_cnt = hdev->acl_pkts;
2424 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002425 break;
2426
2427 case SCO_LINK:
2428 hdev->sco_cnt += count;
2429 if (hdev->sco_cnt > hdev->sco_pkts)
2430 hdev->sco_cnt = hdev->sco_pkts;
2431 break;
2432
2433 default:
2434 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2435 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002436 }
2437 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002438
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002439 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440}
2441
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002442static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2443 struct sk_buff *skb)
2444{
2445 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2446 int i;
2447
2448 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2449 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2450 return;
2451 }
2452
2453 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2454 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2455 BT_DBG("%s bad parameters", hdev->name);
2456 return;
2457 }
2458
2459 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2460 ev->num_hndl);
2461
2462 for (i = 0; i < ev->num_hndl; i++) {
2463 struct hci_comp_blocks_info *info = &ev->handles[i];
2464 struct hci_conn *conn;
2465 __u16 handle, block_count;
2466
2467 handle = __le16_to_cpu(info->handle);
2468 block_count = __le16_to_cpu(info->blocks);
2469
2470 conn = hci_conn_hash_lookup_handle(hdev, handle);
2471 if (!conn)
2472 continue;
2473
2474 conn->sent -= block_count;
2475
2476 switch (conn->type) {
2477 case ACL_LINK:
2478 hdev->block_cnt += block_count;
2479 if (hdev->block_cnt > hdev->num_blocks)
2480 hdev->block_cnt = hdev->num_blocks;
2481 break;
2482
2483 default:
2484 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2485 break;
2486 }
2487 }
2488
2489 queue_work(hdev->workqueue, &hdev->tx_work);
2490}
2491
Marcel Holtmann04837f62006-07-03 10:02:33 +02002492static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002493{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002494 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002495 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496
2497 BT_DBG("%s status %d", hdev->name, ev->status);
2498
2499 hci_dev_lock(hdev);
2500
Marcel Holtmann04837f62006-07-03 10:02:33 +02002501 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2502 if (conn) {
2503 conn->mode = ev->mode;
2504 conn->interval = __le16_to_cpu(ev->interval);
2505
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002506 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002507 if (conn->mode == HCI_CM_ACTIVE)
2508 conn->power_save = 1;
2509 else
2510 conn->power_save = 0;
2511 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002512
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002513 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002514 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002515 }
2516
2517 hci_dev_unlock(hdev);
2518}
2519
Linus Torvalds1da177e2005-04-16 15:20:36 -07002520static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2521{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002522 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2523 struct hci_conn *conn;
2524
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002525 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002526
2527 hci_dev_lock(hdev);
2528
2529 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002530 if (!conn)
2531 goto unlock;
2532
2533 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002534 hci_conn_hold(conn);
2535 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2536 hci_conn_put(conn);
2537 }
2538
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002539 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002540 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2541 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002542 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002543 u8 secure;
2544
2545 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2546 secure = 1;
2547 else
2548 secure = 0;
2549
Johan Hedberg744cf192011-11-08 20:40:14 +02002550 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002551 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002552
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002553unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002554 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555}
2556
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2558{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002559 struct hci_ev_link_key_req *ev = (void *) skb->data;
2560 struct hci_cp_link_key_reply cp;
2561 struct hci_conn *conn;
2562 struct link_key *key;
2563
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002564 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002565
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002566 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002567 return;
2568
2569 hci_dev_lock(hdev);
2570
2571 key = hci_find_link_key(hdev, &ev->bdaddr);
2572 if (!key) {
2573 BT_DBG("%s link key not found for %s", hdev->name,
2574 batostr(&ev->bdaddr));
2575 goto not_found;
2576 }
2577
2578 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2579 batostr(&ev->bdaddr));
2580
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002581 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002582 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002583 BT_DBG("%s ignoring debug key", hdev->name);
2584 goto not_found;
2585 }
2586
2587 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002588 if (conn) {
2589 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2590 conn->auth_type != 0xff &&
2591 (conn->auth_type & 0x01)) {
2592 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2593 goto not_found;
2594 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002595
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002596 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2597 conn->pending_sec_level == BT_SECURITY_HIGH) {
2598 BT_DBG("%s ignoring key unauthenticated for high \
2599 security", hdev->name);
2600 goto not_found;
2601 }
2602
2603 conn->key_type = key->type;
2604 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002605 }
2606
2607 bacpy(&cp.bdaddr, &ev->bdaddr);
2608 memcpy(cp.link_key, key->val, 16);
2609
2610 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2611
2612 hci_dev_unlock(hdev);
2613
2614 return;
2615
2616not_found:
2617 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2618 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619}
2620
Linus Torvalds1da177e2005-04-16 15:20:36 -07002621static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2622{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002623 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2624 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002625 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002626
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002627 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002628
2629 hci_dev_lock(hdev);
2630
2631 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2632 if (conn) {
2633 hci_conn_hold(conn);
2634 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002635 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002636
2637 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2638 conn->key_type = ev->key_type;
2639
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002640 hci_conn_put(conn);
2641 }
2642
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002643 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002644 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002645 ev->key_type, pin_len);
2646
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002647 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002648}
2649
Marcel Holtmann04837f62006-07-03 10:02:33 +02002650static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2651{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002652 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002653 struct hci_conn *conn;
2654
2655 BT_DBG("%s status %d", hdev->name, ev->status);
2656
2657 hci_dev_lock(hdev);
2658
2659 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660 if (conn && !ev->status) {
2661 struct inquiry_entry *ie;
2662
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002663 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2664 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665 ie->data.clock_offset = ev->clock_offset;
2666 ie->timestamp = jiffies;
2667 }
2668 }
2669
2670 hci_dev_unlock(hdev);
2671}
2672
Marcel Holtmanna8746412008-07-14 20:13:46 +02002673static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2674{
2675 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2676 struct hci_conn *conn;
2677
2678 BT_DBG("%s status %d", hdev->name, ev->status);
2679
2680 hci_dev_lock(hdev);
2681
2682 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2683 if (conn && !ev->status)
2684 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2685
2686 hci_dev_unlock(hdev);
2687}
2688
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002689static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2690{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002691 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002692 struct inquiry_entry *ie;
2693
2694 BT_DBG("%s", hdev->name);
2695
2696 hci_dev_lock(hdev);
2697
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002698 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2699 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002700 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2701 ie->timestamp = jiffies;
2702 }
2703
2704 hci_dev_unlock(hdev);
2705}
2706
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002707static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2708{
2709 struct inquiry_data data;
2710 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg31754052012-01-04 13:39:52 +02002711 bool name_known;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002712
2713 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2714
2715 if (!num_rsp)
2716 return;
2717
2718 hci_dev_lock(hdev);
2719
2720 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002721 struct inquiry_info_with_rssi_and_pscan_mode *info;
2722 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002723
Johan Hedberge17acd42011-03-30 23:57:16 +03002724 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002725 bacpy(&data.bdaddr, &info->bdaddr);
2726 data.pscan_rep_mode = info->pscan_rep_mode;
2727 data.pscan_period_mode = info->pscan_period_mode;
2728 data.pscan_mode = info->pscan_mode;
2729 memcpy(data.dev_class, info->dev_class, 3);
2730 data.clock_offset = info->clock_offset;
2731 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002732 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002733
2734 name_known = hci_inquiry_cache_update(hdev, &data,
2735 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002736 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002737 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002738 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002739 }
2740 } else {
2741 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2742
Johan Hedberge17acd42011-03-30 23:57:16 +03002743 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002744 bacpy(&data.bdaddr, &info->bdaddr);
2745 data.pscan_rep_mode = info->pscan_rep_mode;
2746 data.pscan_period_mode = info->pscan_period_mode;
2747 data.pscan_mode = 0x00;
2748 memcpy(data.dev_class, info->dev_class, 3);
2749 data.clock_offset = info->clock_offset;
2750 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002751 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002752 name_known = hci_inquiry_cache_update(hdev, &data,
2753 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002754 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002755 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002756 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002757 }
2758 }
2759
2760 hci_dev_unlock(hdev);
2761}
2762
2763static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2764{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002765 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2766 struct hci_conn *conn;
2767
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002768 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002769
Marcel Holtmann41a96212008-07-14 20:13:48 +02002770 hci_dev_lock(hdev);
2771
2772 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002773 if (!conn)
2774 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002775
Johan Hedbergccd556f2010-11-10 17:11:51 +02002776 if (!ev->status && ev->page == 0x01) {
2777 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002778
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002779 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2780 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002781 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002782
Johan Hedbergccd556f2010-11-10 17:11:51 +02002783 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002784 }
2785
Johan Hedbergccd556f2010-11-10 17:11:51 +02002786 if (conn->state != BT_CONFIG)
2787 goto unlock;
2788
Johan Hedberg127178d2010-11-18 22:22:29 +02002789 if (!ev->status) {
2790 struct hci_cp_remote_name_req cp;
2791 memset(&cp, 0, sizeof(cp));
2792 bacpy(&cp.bdaddr, &conn->dst);
2793 cp.pscan_rep_mode = 0x02;
2794 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002795 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2796 mgmt_device_connected(hdev, &conn->dst, conn->type,
2797 conn->dst_type, NULL, 0,
2798 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002799
Johan Hedberg127178d2010-11-18 22:22:29 +02002800 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002801 conn->state = BT_CONNECTED;
2802 hci_proto_connect_cfm(conn, ev->status);
2803 hci_conn_put(conn);
2804 }
2805
2806unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002807 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002808}
2809
2810static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2811{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002812 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2813 struct hci_conn *conn;
2814
2815 BT_DBG("%s status %d", hdev->name, ev->status);
2816
2817 hci_dev_lock(hdev);
2818
2819 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002820 if (!conn) {
2821 if (ev->link_type == ESCO_LINK)
2822 goto unlock;
2823
2824 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2825 if (!conn)
2826 goto unlock;
2827
2828 conn->type = SCO_LINK;
2829 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002830
Marcel Holtmann732547f2009-04-19 19:14:14 +02002831 switch (ev->status) {
2832 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002833 conn->handle = __le16_to_cpu(ev->handle);
2834 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002835
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002836 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002837 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002838 break;
2839
Stephen Coe705e5712010-02-16 11:29:44 -05002840 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002841 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002842 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002843 case 0x1f: /* Unspecified error */
2844 if (conn->out && conn->attempt < 2) {
2845 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2846 (hdev->esco_type & EDR_ESCO_MASK);
2847 hci_setup_sync(conn, conn->link->handle);
2848 goto unlock;
2849 }
2850 /* fall through */
2851
2852 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002853 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002854 break;
2855 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002856
2857 hci_proto_connect_cfm(conn, ev->status);
2858 if (ev->status)
2859 hci_conn_del(conn);
2860
2861unlock:
2862 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002863}
2864
2865static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2866{
2867 BT_DBG("%s", hdev->name);
2868}
2869
Marcel Holtmann04837f62006-07-03 10:02:33 +02002870static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2871{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002872 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002873
2874 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002875}
2876
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002877static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2878{
2879 struct inquiry_data data;
2880 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2881 int num_rsp = *((__u8 *) skb->data);
2882
2883 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2884
2885 if (!num_rsp)
2886 return;
2887
2888 hci_dev_lock(hdev);
2889
Johan Hedberge17acd42011-03-30 23:57:16 +03002890 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg561aafb2012-01-04 13:31:59 +02002891 bool name_known;
2892
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002893 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002894 data.pscan_rep_mode = info->pscan_rep_mode;
2895 data.pscan_period_mode = info->pscan_period_mode;
2896 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002897 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002898 data.clock_offset = info->clock_offset;
2899 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002900 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002901
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002902 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002903 name_known = eir_has_data_type(info->data,
2904 sizeof(info->data),
2905 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002906 else
2907 name_known = true;
2908
Johan Hedberg31754052012-01-04 13:39:52 +02002909 name_known = hci_inquiry_cache_update(hdev, &data, name_known);
Johan Hedberg48264f02011-11-09 13:58:58 +02002910 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002911 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002912 !name_known, info->data,
2913 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002914 }
2915
2916 hci_dev_unlock(hdev);
2917}
2918
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002919static inline u8 hci_get_auth_req(struct hci_conn *conn)
2920{
2921 /* If remote requests dedicated bonding follow that lead */
2922 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2923 /* If both remote and local IO capabilities allow MITM
2924 * protection then require it, otherwise don't */
2925 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2926 return 0x02;
2927 else
2928 return 0x03;
2929 }
2930
2931 /* If remote requests no-bonding follow that lead */
2932 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002933 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002934
2935 return conn->auth_type;
2936}
2937
Marcel Holtmann04936842008-07-14 20:13:48 +02002938static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2939{
2940 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2941 struct hci_conn *conn;
2942
2943 BT_DBG("%s", hdev->name);
2944
2945 hci_dev_lock(hdev);
2946
2947 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002948 if (!conn)
2949 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002950
Johan Hedberg03b555e2011-01-04 15:40:05 +02002951 hci_conn_hold(conn);
2952
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002953 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002954 goto unlock;
2955
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002956 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02002957 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002958 struct hci_cp_io_capability_reply cp;
2959
2960 bacpy(&cp.bdaddr, &ev->bdaddr);
2961 cp.capability = conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07002962 conn->auth_type = hci_get_auth_req(conn);
2963 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002964
Szymon Jancce85ee12011-03-22 13:12:23 +01002965 if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
2966 hci_find_remote_oob_data(hdev, &conn->dst))
2967 cp.oob_data = 0x01;
2968 else
2969 cp.oob_data = 0x00;
2970
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002971 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2972 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002973 } else {
2974 struct hci_cp_io_capability_neg_reply cp;
2975
2976 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002977 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02002978
2979 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2980 sizeof(cp), &cp);
2981 }
2982
2983unlock:
2984 hci_dev_unlock(hdev);
2985}
2986
2987static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2988{
2989 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2990 struct hci_conn *conn;
2991
2992 BT_DBG("%s", hdev->name);
2993
2994 hci_dev_lock(hdev);
2995
2996 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2997 if (!conn)
2998 goto unlock;
2999
Johan Hedberg03b555e2011-01-04 15:40:05 +02003000 conn->remote_cap = ev->capability;
3001 conn->remote_oob = ev->oob_data;
3002 conn->remote_auth = ev->authentication;
3003
3004unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003005 hci_dev_unlock(hdev);
3006}
3007
Johan Hedberga5c29682011-02-19 12:05:57 -03003008static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3009 struct sk_buff *skb)
3010{
3011 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003012 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003013 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003014
3015 BT_DBG("%s", hdev->name);
3016
3017 hci_dev_lock(hdev);
3018
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003019 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003020 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003021
Johan Hedberg7a828902011-04-28 11:28:53 -07003022 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3023 if (!conn)
3024 goto unlock;
3025
3026 loc_mitm = (conn->auth_type & 0x01);
3027 rem_mitm = (conn->remote_auth & 0x01);
3028
3029 /* If we require MITM but the remote device can't provide that
3030 * (it has NoInputNoOutput) then reject the confirmation
3031 * request. The only exception is when we're dedicated bonding
3032 * initiators (connect_cfm_cb set) since then we always have the MITM
3033 * bit set. */
3034 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3035 BT_DBG("Rejecting request: remote device can't provide MITM");
3036 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3037 sizeof(ev->bdaddr), &ev->bdaddr);
3038 goto unlock;
3039 }
3040
3041 /* If no side requires MITM protection; auto-accept */
3042 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3043 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003044
3045 /* If we're not the initiators request authorization to
3046 * proceed from user space (mgmt_user_confirm with
3047 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003048 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003049 BT_DBG("Confirming auto-accept as acceptor");
3050 confirm_hint = 1;
3051 goto confirm;
3052 }
3053
Johan Hedberg9f616562011-04-28 11:28:54 -07003054 BT_DBG("Auto-accept of user confirmation with %ums delay",
3055 hdev->auto_accept_delay);
3056
3057 if (hdev->auto_accept_delay > 0) {
3058 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3059 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3060 goto unlock;
3061 }
3062
Johan Hedberg7a828902011-04-28 11:28:53 -07003063 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3064 sizeof(ev->bdaddr), &ev->bdaddr);
3065 goto unlock;
3066 }
3067
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003068confirm:
Johan Hedberg744cf192011-11-08 20:40:14 +02003069 mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003070 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003071
3072unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003073 hci_dev_unlock(hdev);
3074}
3075
Brian Gix1143d452011-11-23 08:28:34 -08003076static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3077 struct sk_buff *skb)
3078{
3079 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3080
3081 BT_DBG("%s", hdev->name);
3082
3083 hci_dev_lock(hdev);
3084
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003085 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08003086 mgmt_user_passkey_request(hdev, &ev->bdaddr);
3087
3088 hci_dev_unlock(hdev);
3089}
3090
Marcel Holtmann04936842008-07-14 20:13:48 +02003091static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3092{
3093 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3094 struct hci_conn *conn;
3095
3096 BT_DBG("%s", hdev->name);
3097
3098 hci_dev_lock(hdev);
3099
3100 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003101 if (!conn)
3102 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003103
Johan Hedberg2a611692011-02-19 12:06:00 -03003104 /* To avoid duplicate auth_failed events to user space we check
3105 * the HCI_CONN_AUTH_PEND flag which will be set if we
3106 * initiated the authentication. A traditional auth_complete
3107 * event gets always produced as initiator and is also mapped to
3108 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003109 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedberg744cf192011-11-08 20:40:14 +02003110 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003111
3112 hci_conn_put(conn);
3113
3114unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003115 hci_dev_unlock(hdev);
3116}
3117
Marcel Holtmann41a96212008-07-14 20:13:48 +02003118static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3119{
3120 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3121 struct inquiry_entry *ie;
3122
3123 BT_DBG("%s", hdev->name);
3124
3125 hci_dev_lock(hdev);
3126
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003127 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3128 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003129 ie->data.ssp_mode = (ev->features[0] & 0x01);
3130
3131 hci_dev_unlock(hdev);
3132}
3133
Szymon Janc2763eda2011-03-22 13:12:22 +01003134static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3135 struct sk_buff *skb)
3136{
3137 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3138 struct oob_data *data;
3139
3140 BT_DBG("%s", hdev->name);
3141
3142 hci_dev_lock(hdev);
3143
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003144 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003145 goto unlock;
3146
Szymon Janc2763eda2011-03-22 13:12:22 +01003147 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3148 if (data) {
3149 struct hci_cp_remote_oob_data_reply cp;
3150
3151 bacpy(&cp.bdaddr, &ev->bdaddr);
3152 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3153 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3154
3155 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3156 &cp);
3157 } else {
3158 struct hci_cp_remote_oob_data_neg_reply cp;
3159
3160 bacpy(&cp.bdaddr, &ev->bdaddr);
3161 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3162 &cp);
3163 }
3164
Szymon Jance1ba1f12011-04-06 13:01:59 +02003165unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003166 hci_dev_unlock(hdev);
3167}
3168
Ville Tervofcd89c02011-02-10 22:38:47 -03003169static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3170{
3171 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3172 struct hci_conn *conn;
3173
3174 BT_DBG("%s status %d", hdev->name, ev->status);
3175
3176 hci_dev_lock(hdev);
3177
3178 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003179 if (!conn) {
3180 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3181 if (!conn) {
3182 BT_ERR("No memory for new connection");
3183 hci_dev_unlock(hdev);
3184 return;
3185 }
Andre Guedes29b79882011-05-31 14:20:54 -03003186
3187 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003188 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003189
3190 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003191 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3192 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003193 hci_proto_connect_cfm(conn, ev->status);
3194 conn->state = BT_CLOSED;
3195 hci_conn_del(conn);
3196 goto unlock;
3197 }
3198
Johan Hedbergb644ba32012-01-17 21:48:47 +02003199 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3200 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3201 conn->dst_type, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003202
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003203 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003204 conn->handle = __le16_to_cpu(ev->handle);
3205 conn->state = BT_CONNECTED;
3206
3207 hci_conn_hold_device(conn);
3208 hci_conn_add_sysfs(conn);
3209
3210 hci_proto_connect_cfm(conn, ev->status);
3211
3212unlock:
3213 hci_dev_unlock(hdev);
3214}
3215
Andre Guedes9aa04c92011-05-26 16:23:51 -03003216static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3217 struct sk_buff *skb)
3218{
Andre Guedese95beb42011-09-26 20:48:35 -03003219 u8 num_reports = skb->data[0];
3220 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003221 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003222
3223 hci_dev_lock(hdev);
3224
Andre Guedese95beb42011-09-26 20:48:35 -03003225 while (num_reports--) {
3226 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003227
Andre Guedes9aa04c92011-05-26 16:23:51 -03003228 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003229
Andre Guedes3c9e9192012-01-10 18:20:50 -03003230 rssi = ev->data[ev->length];
3231 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3232 NULL, rssi, 0, ev->data, ev->length);
3233
Andre Guedese95beb42011-09-26 20:48:35 -03003234 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003235 }
3236
3237 hci_dev_unlock(hdev);
3238}
3239
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003240static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3241 struct sk_buff *skb)
3242{
3243 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3244 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003245 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003246 struct hci_conn *conn;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003247 struct link_key *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003248
3249 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3250
3251 hci_dev_lock(hdev);
3252
3253 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003254 if (conn == NULL)
3255 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003256
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003257 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3258 if (ltk == NULL)
3259 goto not_found;
3260
3261 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003262 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes726b4ff2011-07-08 18:31:45 -03003263 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003264
3265 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3266
3267 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003268
3269 return;
3270
3271not_found:
3272 neg.handle = ev->handle;
3273 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3274 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003275}
3276
Ville Tervofcd89c02011-02-10 22:38:47 -03003277static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3278{
3279 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3280
3281 skb_pull(skb, sizeof(*le_ev));
3282
3283 switch (le_ev->subevent) {
3284 case HCI_EV_LE_CONN_COMPLETE:
3285 hci_le_conn_complete_evt(hdev, skb);
3286 break;
3287
Andre Guedes9aa04c92011-05-26 16:23:51 -03003288 case HCI_EV_LE_ADVERTISING_REPORT:
3289 hci_le_adv_report_evt(hdev, skb);
3290 break;
3291
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003292 case HCI_EV_LE_LTK_REQ:
3293 hci_le_ltk_request_evt(hdev, skb);
3294 break;
3295
Ville Tervofcd89c02011-02-10 22:38:47 -03003296 default:
3297 break;
3298 }
3299}
3300
Linus Torvalds1da177e2005-04-16 15:20:36 -07003301void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3302{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003303 struct hci_event_hdr *hdr = (void *) skb->data;
3304 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003305
3306 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3307
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003308 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003309 case HCI_EV_INQUIRY_COMPLETE:
3310 hci_inquiry_complete_evt(hdev, skb);
3311 break;
3312
3313 case HCI_EV_INQUIRY_RESULT:
3314 hci_inquiry_result_evt(hdev, skb);
3315 break;
3316
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003317 case HCI_EV_CONN_COMPLETE:
3318 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003319 break;
3320
Linus Torvalds1da177e2005-04-16 15:20:36 -07003321 case HCI_EV_CONN_REQUEST:
3322 hci_conn_request_evt(hdev, skb);
3323 break;
3324
Linus Torvalds1da177e2005-04-16 15:20:36 -07003325 case HCI_EV_DISCONN_COMPLETE:
3326 hci_disconn_complete_evt(hdev, skb);
3327 break;
3328
Linus Torvalds1da177e2005-04-16 15:20:36 -07003329 case HCI_EV_AUTH_COMPLETE:
3330 hci_auth_complete_evt(hdev, skb);
3331 break;
3332
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003333 case HCI_EV_REMOTE_NAME:
3334 hci_remote_name_evt(hdev, skb);
3335 break;
3336
Linus Torvalds1da177e2005-04-16 15:20:36 -07003337 case HCI_EV_ENCRYPT_CHANGE:
3338 hci_encrypt_change_evt(hdev, skb);
3339 break;
3340
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003341 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3342 hci_change_link_key_complete_evt(hdev, skb);
3343 break;
3344
3345 case HCI_EV_REMOTE_FEATURES:
3346 hci_remote_features_evt(hdev, skb);
3347 break;
3348
3349 case HCI_EV_REMOTE_VERSION:
3350 hci_remote_version_evt(hdev, skb);
3351 break;
3352
3353 case HCI_EV_QOS_SETUP_COMPLETE:
3354 hci_qos_setup_complete_evt(hdev, skb);
3355 break;
3356
3357 case HCI_EV_CMD_COMPLETE:
3358 hci_cmd_complete_evt(hdev, skb);
3359 break;
3360
3361 case HCI_EV_CMD_STATUS:
3362 hci_cmd_status_evt(hdev, skb);
3363 break;
3364
3365 case HCI_EV_ROLE_CHANGE:
3366 hci_role_change_evt(hdev, skb);
3367 break;
3368
3369 case HCI_EV_NUM_COMP_PKTS:
3370 hci_num_comp_pkts_evt(hdev, skb);
3371 break;
3372
3373 case HCI_EV_MODE_CHANGE:
3374 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003375 break;
3376
3377 case HCI_EV_PIN_CODE_REQ:
3378 hci_pin_code_request_evt(hdev, skb);
3379 break;
3380
3381 case HCI_EV_LINK_KEY_REQ:
3382 hci_link_key_request_evt(hdev, skb);
3383 break;
3384
3385 case HCI_EV_LINK_KEY_NOTIFY:
3386 hci_link_key_notify_evt(hdev, skb);
3387 break;
3388
3389 case HCI_EV_CLOCK_OFFSET:
3390 hci_clock_offset_evt(hdev, skb);
3391 break;
3392
Marcel Holtmanna8746412008-07-14 20:13:46 +02003393 case HCI_EV_PKT_TYPE_CHANGE:
3394 hci_pkt_type_change_evt(hdev, skb);
3395 break;
3396
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003397 case HCI_EV_PSCAN_REP_MODE:
3398 hci_pscan_rep_mode_evt(hdev, skb);
3399 break;
3400
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003401 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3402 hci_inquiry_result_with_rssi_evt(hdev, skb);
3403 break;
3404
3405 case HCI_EV_REMOTE_EXT_FEATURES:
3406 hci_remote_ext_features_evt(hdev, skb);
3407 break;
3408
3409 case HCI_EV_SYNC_CONN_COMPLETE:
3410 hci_sync_conn_complete_evt(hdev, skb);
3411 break;
3412
3413 case HCI_EV_SYNC_CONN_CHANGED:
3414 hci_sync_conn_changed_evt(hdev, skb);
3415 break;
3416
Marcel Holtmann04837f62006-07-03 10:02:33 +02003417 case HCI_EV_SNIFF_SUBRATE:
3418 hci_sniff_subrate_evt(hdev, skb);
3419 break;
3420
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003421 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3422 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423 break;
3424
Marcel Holtmann04936842008-07-14 20:13:48 +02003425 case HCI_EV_IO_CAPA_REQUEST:
3426 hci_io_capa_request_evt(hdev, skb);
3427 break;
3428
Johan Hedberg03b555e2011-01-04 15:40:05 +02003429 case HCI_EV_IO_CAPA_REPLY:
3430 hci_io_capa_reply_evt(hdev, skb);
3431 break;
3432
Johan Hedberga5c29682011-02-19 12:05:57 -03003433 case HCI_EV_USER_CONFIRM_REQUEST:
3434 hci_user_confirm_request_evt(hdev, skb);
3435 break;
3436
Brian Gix1143d452011-11-23 08:28:34 -08003437 case HCI_EV_USER_PASSKEY_REQUEST:
3438 hci_user_passkey_request_evt(hdev, skb);
3439 break;
3440
Marcel Holtmann04936842008-07-14 20:13:48 +02003441 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3442 hci_simple_pair_complete_evt(hdev, skb);
3443 break;
3444
Marcel Holtmann41a96212008-07-14 20:13:48 +02003445 case HCI_EV_REMOTE_HOST_FEATURES:
3446 hci_remote_host_features_evt(hdev, skb);
3447 break;
3448
Ville Tervofcd89c02011-02-10 22:38:47 -03003449 case HCI_EV_LE_META:
3450 hci_le_meta_evt(hdev, skb);
3451 break;
3452
Szymon Janc2763eda2011-03-22 13:12:22 +01003453 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3454 hci_remote_oob_data_request_evt(hdev, skb);
3455 break;
3456
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003457 case HCI_EV_NUM_COMP_BLOCKS:
3458 hci_num_comp_blocks_evt(hdev, skb);
3459 break;
3460
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003461 default:
3462 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003463 break;
3464 }
3465
3466 kfree_skb(skb);
3467 hdev->stat.evt_rx++;
3468}
3469
3470/* Generate internal stack event */
3471void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3472{
3473 struct hci_event_hdr *hdr;
3474 struct hci_ev_stack_internal *ev;
3475 struct sk_buff *skb;
3476
3477 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3478 if (!skb)
3479 return;
3480
3481 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3482 hdr->evt = HCI_EV_STACK_INTERNAL;
3483 hdr->plen = sizeof(*ev) + dlen;
3484
3485 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3486 ev->type = type;
3487 memcpy(ev->data, data, dlen);
3488
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003489 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003490 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003491
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003492 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003493 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003494 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003495 kfree_skb(skb);
3496}
Andre Guedese6100a22011-06-30 19:20:54 -03003497
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003498module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003499MODULE_PARM_DESC(enable_le, "Enable LE support");