blob: 02ad538017329c9c70ad3d19a2093972912aa56e [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 Emeltchenkoe61ef492011-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 Hedberg58a681e2012-01-16 06:47:28 +02001267 if (!(hdev->ssp_mode > 0 &&
1268 test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001269 conn->pending_sec_level != BT_SECURITY_HIGH &&
1270 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001271 return 0;
1272
Johan Hedberg392599b2010-11-18 22:22:28 +02001273 return 1;
1274}
1275
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001276static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1277{
1278 struct hci_cp_remote_name_req cp;
1279
1280 memset(&cp, 0, sizeof(cp));
1281
1282 bacpy(&cp.bdaddr, &e->data.bdaddr);
1283 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1284 cp.pscan_mode = e->data.pscan_mode;
1285 cp.clock_offset = e->data.clock_offset;
1286
1287 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1288}
1289
Johan Hedbergb644ba32012-01-17 21:48:47 +02001290static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001291{
1292 struct discovery_state *discov = &hdev->discovery;
1293 struct inquiry_entry *e;
1294
Johan Hedbergb644ba32012-01-17 21:48:47 +02001295 if (list_empty(&discov->resolve))
1296 return false;
1297
1298 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1299 if (hci_resolve_name(hdev, e) == 0) {
1300 e->name_state = NAME_PENDING;
1301 return true;
1302 }
1303
1304 return false;
1305}
1306
1307static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1308 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1309{
1310 struct discovery_state *discov = &hdev->discovery;
1311 struct inquiry_entry *e;
1312
1313 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1314 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
1315 name, name_len, conn->dev_class);
1316
1317 if (discov->state == DISCOVERY_STOPPED)
1318 return;
1319
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001320 if (discov->state == DISCOVERY_STOPPING)
1321 goto discov_complete;
1322
1323 if (discov->state != DISCOVERY_RESOLVING)
1324 return;
1325
1326 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1327 if (e) {
1328 e->name_state = NAME_KNOWN;
1329 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001330 if (name)
1331 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1332 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001333 }
1334
Johan Hedbergb644ba32012-01-17 21:48:47 +02001335 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001336 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001337
1338discov_complete:
1339 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1340}
1341
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001342static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1343{
Johan Hedberg127178d2010-11-18 22:22:29 +02001344 struct hci_cp_remote_name_req *cp;
1345 struct hci_conn *conn;
1346
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001347 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001348
1349 /* If successful wait for the name req complete event before
1350 * checking for the need to do authentication */
1351 if (!status)
1352 return;
1353
1354 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1355 if (!cp)
1356 return;
1357
1358 hci_dev_lock(hdev);
1359
1360 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001361
1362 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1363 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1364
Johan Hedberg79c6c702011-04-28 11:28:55 -07001365 if (!conn)
1366 goto unlock;
1367
1368 if (!hci_outgoing_auth_needed(hdev, conn))
1369 goto unlock;
1370
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001371 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001372 struct hci_cp_auth_requested cp;
1373 cp.handle = __cpu_to_le16(conn->handle);
1374 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1375 }
1376
Johan Hedberg79c6c702011-04-28 11:28:55 -07001377unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001378 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001379}
1380
Marcel Holtmann769be972008-07-14 20:13:49 +02001381static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1382{
1383 struct hci_cp_read_remote_features *cp;
1384 struct hci_conn *conn;
1385
1386 BT_DBG("%s status 0x%x", hdev->name, status);
1387
1388 if (!status)
1389 return;
1390
1391 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1392 if (!cp)
1393 return;
1394
1395 hci_dev_lock(hdev);
1396
1397 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1398 if (conn) {
1399 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001400 hci_proto_connect_cfm(conn, status);
1401 hci_conn_put(conn);
1402 }
1403 }
1404
1405 hci_dev_unlock(hdev);
1406}
1407
1408static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1409{
1410 struct hci_cp_read_remote_ext_features *cp;
1411 struct hci_conn *conn;
1412
1413 BT_DBG("%s status 0x%x", hdev->name, status);
1414
1415 if (!status)
1416 return;
1417
1418 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1419 if (!cp)
1420 return;
1421
1422 hci_dev_lock(hdev);
1423
1424 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1425 if (conn) {
1426 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001427 hci_proto_connect_cfm(conn, status);
1428 hci_conn_put(conn);
1429 }
1430 }
1431
1432 hci_dev_unlock(hdev);
1433}
1434
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001435static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1436{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001437 struct hci_cp_setup_sync_conn *cp;
1438 struct hci_conn *acl, *sco;
1439 __u16 handle;
1440
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001441 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001442
1443 if (!status)
1444 return;
1445
1446 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1447 if (!cp)
1448 return;
1449
1450 handle = __le16_to_cpu(cp->handle);
1451
1452 BT_DBG("%s handle %d", hdev->name, handle);
1453
1454 hci_dev_lock(hdev);
1455
1456 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001457 if (acl) {
1458 sco = acl->link;
1459 if (sco) {
1460 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001461
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001462 hci_proto_connect_cfm(sco, status);
1463 hci_conn_del(sco);
1464 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001465 }
1466
1467 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001468}
1469
1470static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1471{
1472 struct hci_cp_sniff_mode *cp;
1473 struct hci_conn *conn;
1474
1475 BT_DBG("%s status 0x%x", hdev->name, status);
1476
1477 if (!status)
1478 return;
1479
1480 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1481 if (!cp)
1482 return;
1483
1484 hci_dev_lock(hdev);
1485
1486 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001487 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001488 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001489
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001490 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001491 hci_sco_setup(conn, status);
1492 }
1493
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001494 hci_dev_unlock(hdev);
1495}
1496
1497static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1498{
1499 struct hci_cp_exit_sniff_mode *cp;
1500 struct hci_conn *conn;
1501
1502 BT_DBG("%s status 0x%x", hdev->name, status);
1503
1504 if (!status)
1505 return;
1506
1507 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1508 if (!cp)
1509 return;
1510
1511 hci_dev_lock(hdev);
1512
1513 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001514 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001515 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001516
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001517 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001518 hci_sco_setup(conn, status);
1519 }
1520
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001521 hci_dev_unlock(hdev);
1522}
1523
Ville Tervofcd89c02011-02-10 22:38:47 -03001524static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1525{
1526 struct hci_cp_le_create_conn *cp;
1527 struct hci_conn *conn;
1528
1529 BT_DBG("%s status 0x%x", hdev->name, status);
1530
1531 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1532 if (!cp)
1533 return;
1534
1535 hci_dev_lock(hdev);
1536
1537 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1538
1539 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1540 conn);
1541
1542 if (status) {
1543 if (conn && conn->state == BT_CONNECT) {
1544 conn->state = BT_CLOSED;
1545 hci_proto_connect_cfm(conn, status);
1546 hci_conn_del(conn);
1547 }
1548 } else {
1549 if (!conn) {
1550 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001551 if (conn) {
1552 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001553 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001554 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001555 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001556 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001557 }
1558 }
1559
1560 hci_dev_unlock(hdev);
1561}
1562
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001563static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1564{
1565 BT_DBG("%s status 0x%x", hdev->name, status);
1566}
1567
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001568static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1569{
1570 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001571 struct discovery_state *discov = &hdev->discovery;
1572 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001573
1574 BT_DBG("%s status %d", hdev->name, status);
1575
Johan Hedberg23bb5762010-12-21 23:01:27 +02001576 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001577
1578 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001579
1580 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1581 return;
1582
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001583 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001584 return;
1585
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001586 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001587
1588 if (discov->state != DISCOVERY_INQUIRY)
1589 goto unlock;
1590
1591 if (list_empty(&discov->resolve)) {
1592 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1593 goto unlock;
1594 }
1595
1596 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1597 if (e && hci_resolve_name(hdev, e) == 0) {
1598 e->name_state = NAME_PENDING;
1599 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1600 } else {
1601 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1602 }
1603
1604unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001605 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001606}
1607
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1609{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001610 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001611 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 int num_rsp = *((__u8 *) skb->data);
1613
1614 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1615
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001616 if (!num_rsp)
1617 return;
1618
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001620
Johan Hedberge17acd42011-03-30 23:57:16 +03001621 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg31754052012-01-04 13:39:52 +02001622 bool name_known;
1623
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 bacpy(&data.bdaddr, &info->bdaddr);
1625 data.pscan_rep_mode = info->pscan_rep_mode;
1626 data.pscan_period_mode = info->pscan_period_mode;
1627 data.pscan_mode = info->pscan_mode;
1628 memcpy(data.dev_class, info->dev_class, 3);
1629 data.clock_offset = info->clock_offset;
1630 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001631 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001632
1633 name_known = hci_inquiry_cache_update(hdev, &data, false);
Johan Hedberg48264f02011-11-09 13:58:58 +02001634 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Andre Guedes7d262f82012-01-10 18:20:49 -03001635 info->dev_class, 0, !name_known,
1636 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001638
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 hci_dev_unlock(hdev);
1640}
1641
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001642static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001644 struct hci_ev_conn_complete *ev = (void *) skb->data;
1645 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001647 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001648
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001650
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001651 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001652 if (!conn) {
1653 if (ev->link_type != SCO_LINK)
1654 goto unlock;
1655
1656 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1657 if (!conn)
1658 goto unlock;
1659
1660 conn->type = SCO_LINK;
1661 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001662
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001663 if (!ev->status) {
1664 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001665
1666 if (conn->type == ACL_LINK) {
1667 conn->state = BT_CONFIG;
1668 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001669 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001670 } else
1671 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001672
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001673 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001674 hci_conn_add_sysfs(conn);
1675
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001676 if (test_bit(HCI_AUTH, &hdev->flags))
1677 conn->link_mode |= HCI_LM_AUTH;
1678
1679 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1680 conn->link_mode |= HCI_LM_ENCRYPT;
1681
1682 /* Get remote features */
1683 if (conn->type == ACL_LINK) {
1684 struct hci_cp_read_remote_features cp;
1685 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001686 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1687 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001688 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001689
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001690 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001691 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001692 struct hci_cp_change_conn_ptype cp;
1693 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001694 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1695 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1696 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001697 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001698 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001699 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001700 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001701 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001702 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001703 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001704
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001705 if (conn->type == ACL_LINK)
1706 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001707
Marcel Holtmann769be972008-07-14 20:13:49 +02001708 if (ev->status) {
1709 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001710 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001711 } else if (ev->link_type != ACL_LINK)
1712 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001713
1714unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001716
1717 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718}
1719
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1721{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001722 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 int mask = hdev->link_mode;
1724
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001725 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1726 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727
1728 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1729
Szymon Janc138d22e2011-02-17 16:44:23 +01001730 if ((mask & HCI_LM_ACCEPT) &&
1731 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001733 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735
1736 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001737
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001738 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1739 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001740 memcpy(ie->data.dev_class, ev->dev_class, 3);
1741
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1743 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001744 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1745 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001746 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 hci_dev_unlock(hdev);
1748 return;
1749 }
1750 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001751
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 memcpy(conn->dev_class, ev->dev_class, 3);
1753 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001754
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 hci_dev_unlock(hdev);
1756
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001757 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1758 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001760 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001762 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1763 cp.role = 0x00; /* Become master */
1764 else
1765 cp.role = 0x01; /* Remain slave */
1766
1767 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1768 sizeof(cp), &cp);
1769 } else {
1770 struct hci_cp_accept_sync_conn_req cp;
1771
1772 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001773 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001774
1775 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1776 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1777 cp.max_latency = cpu_to_le16(0xffff);
1778 cp.content_format = cpu_to_le16(hdev->voice_setting);
1779 cp.retrans_effort = 0xff;
1780
1781 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1782 sizeof(cp), &cp);
1783 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 } else {
1785 /* Connection rejected */
1786 struct hci_cp_reject_conn_req cp;
1787
1788 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001789 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001790 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 }
1792}
1793
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1795{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001796 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001797 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798
1799 BT_DBG("%s status %d", hdev->name, ev->status);
1800
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 hci_dev_lock(hdev);
1802
Marcel Holtmann04837f62006-07-03 10:02:33 +02001803 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001804 if (!conn)
1805 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001806
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001807 if (ev->status == 0)
1808 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809
Johan Hedbergb644ba32012-01-17 21:48:47 +02001810 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1811 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001812 if (ev->status != 0)
1813 mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
1814 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001815 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001816 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001817 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001818
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001819 if (ev->status == 0) {
1820 hci_proto_disconn_cfm(conn, ev->reason);
1821 hci_conn_del(conn);
1822 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001823
1824unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 hci_dev_unlock(hdev);
1826}
1827
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001828static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1829{
1830 struct hci_ev_auth_complete *ev = (void *) skb->data;
1831 struct hci_conn *conn;
1832
1833 BT_DBG("%s status %d", hdev->name, ev->status);
1834
1835 hci_dev_lock(hdev);
1836
1837 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001838 if (!conn)
1839 goto unlock;
1840
1841 if (!ev->status) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02001842 if (!(test_bit(HCI_CONN_SSP_ENABLED, &conn->flags) &&
1843 hdev->ssp_mode > 0) &&
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001844 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001845 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001846 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001847 conn->link_mode |= HCI_LM_AUTH;
1848 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001849 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001850 } else {
Johan Hedberg744cf192011-11-08 20:40:14 +02001851 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001852 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001853
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001854 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1855 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001856
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001857 if (conn->state == BT_CONFIG) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02001858 if (!ev->status && hdev->ssp_mode > 0 &&
1859 test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001860 struct hci_cp_set_conn_encrypt cp;
1861 cp.handle = ev->handle;
1862 cp.encrypt = 0x01;
1863 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1864 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001865 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001866 conn->state = BT_CONNECTED;
1867 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001868 hci_conn_put(conn);
1869 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001870 } else {
1871 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001872
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001873 hci_conn_hold(conn);
1874 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1875 hci_conn_put(conn);
1876 }
1877
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001878 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001879 if (!ev->status) {
1880 struct hci_cp_set_conn_encrypt cp;
1881 cp.handle = ev->handle;
1882 cp.encrypt = 0x01;
1883 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1884 &cp);
1885 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001886 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001887 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001888 }
1889 }
1890
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001891unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001892 hci_dev_unlock(hdev);
1893}
1894
1895static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1896{
Johan Hedberg127178d2010-11-18 22:22:29 +02001897 struct hci_ev_remote_name *ev = (void *) skb->data;
1898 struct hci_conn *conn;
1899
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001900 BT_DBG("%s", hdev->name);
1901
1902 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001903
1904 hci_dev_lock(hdev);
1905
1906 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001907
1908 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1909 goto check_auth;
1910
1911 if (ev->status == 0)
1912 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1913 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1914 else
1915 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1916
1917check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001918 if (!conn)
1919 goto unlock;
1920
1921 if (!hci_outgoing_auth_needed(hdev, conn))
1922 goto unlock;
1923
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001924 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001925 struct hci_cp_auth_requested cp;
1926 cp.handle = __cpu_to_le16(conn->handle);
1927 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1928 }
1929
Johan Hedberg79c6c702011-04-28 11:28:55 -07001930unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001931 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001932}
1933
1934static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1935{
1936 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1937 struct hci_conn *conn;
1938
1939 BT_DBG("%s status %d", hdev->name, ev->status);
1940
1941 hci_dev_lock(hdev);
1942
1943 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1944 if (conn) {
1945 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001946 if (ev->encrypt) {
1947 /* Encryption implies authentication */
1948 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001949 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001950 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001951 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001952 conn->link_mode &= ~HCI_LM_ENCRYPT;
1953 }
1954
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001955 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001956
Marcel Holtmannf8558552008-07-14 20:13:49 +02001957 if (conn->state == BT_CONFIG) {
1958 if (!ev->status)
1959 conn->state = BT_CONNECTED;
1960
1961 hci_proto_connect_cfm(conn, ev->status);
1962 hci_conn_put(conn);
1963 } else
1964 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001965 }
1966
1967 hci_dev_unlock(hdev);
1968}
1969
1970static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1971{
1972 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1973 struct hci_conn *conn;
1974
1975 BT_DBG("%s status %d", hdev->name, ev->status);
1976
1977 hci_dev_lock(hdev);
1978
1979 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1980 if (conn) {
1981 if (!ev->status)
1982 conn->link_mode |= HCI_LM_SECURE;
1983
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001984 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001985
1986 hci_key_change_cfm(conn, ev->status);
1987 }
1988
1989 hci_dev_unlock(hdev);
1990}
1991
1992static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1993{
1994 struct hci_ev_remote_features *ev = (void *) skb->data;
1995 struct hci_conn *conn;
1996
1997 BT_DBG("%s status %d", hdev->name, ev->status);
1998
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001999 hci_dev_lock(hdev);
2000
2001 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002002 if (!conn)
2003 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002004
Johan Hedbergccd556f2010-11-10 17:11:51 +02002005 if (!ev->status)
2006 memcpy(conn->features, ev->features, 8);
2007
2008 if (conn->state != BT_CONFIG)
2009 goto unlock;
2010
2011 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2012 struct hci_cp_read_remote_ext_features cp;
2013 cp.handle = ev->handle;
2014 cp.page = 0x01;
2015 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002016 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002017 goto unlock;
2018 }
2019
Johan Hedberg127178d2010-11-18 22:22:29 +02002020 if (!ev->status) {
2021 struct hci_cp_remote_name_req cp;
2022 memset(&cp, 0, sizeof(cp));
2023 bacpy(&cp.bdaddr, &conn->dst);
2024 cp.pscan_rep_mode = 0x02;
2025 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002026 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2027 mgmt_device_connected(hdev, &conn->dst, conn->type,
2028 conn->dst_type, NULL, 0,
2029 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002030
Johan Hedberg127178d2010-11-18 22:22:29 +02002031 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002032 conn->state = BT_CONNECTED;
2033 hci_proto_connect_cfm(conn, ev->status);
2034 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002035 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002036
Johan Hedbergccd556f2010-11-10 17:11:51 +02002037unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002038 hci_dev_unlock(hdev);
2039}
2040
2041static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2042{
2043 BT_DBG("%s", hdev->name);
2044}
2045
2046static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2047{
2048 BT_DBG("%s", hdev->name);
2049}
2050
2051static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2052{
2053 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2054 __u16 opcode;
2055
2056 skb_pull(skb, sizeof(*ev));
2057
2058 opcode = __le16_to_cpu(ev->opcode);
2059
2060 switch (opcode) {
2061 case HCI_OP_INQUIRY_CANCEL:
2062 hci_cc_inquiry_cancel(hdev, skb);
2063 break;
2064
2065 case HCI_OP_EXIT_PERIODIC_INQ:
2066 hci_cc_exit_periodic_inq(hdev, skb);
2067 break;
2068
2069 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2070 hci_cc_remote_name_req_cancel(hdev, skb);
2071 break;
2072
2073 case HCI_OP_ROLE_DISCOVERY:
2074 hci_cc_role_discovery(hdev, skb);
2075 break;
2076
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002077 case HCI_OP_READ_LINK_POLICY:
2078 hci_cc_read_link_policy(hdev, skb);
2079 break;
2080
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002081 case HCI_OP_WRITE_LINK_POLICY:
2082 hci_cc_write_link_policy(hdev, skb);
2083 break;
2084
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002085 case HCI_OP_READ_DEF_LINK_POLICY:
2086 hci_cc_read_def_link_policy(hdev, skb);
2087 break;
2088
2089 case HCI_OP_WRITE_DEF_LINK_POLICY:
2090 hci_cc_write_def_link_policy(hdev, skb);
2091 break;
2092
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002093 case HCI_OP_RESET:
2094 hci_cc_reset(hdev, skb);
2095 break;
2096
2097 case HCI_OP_WRITE_LOCAL_NAME:
2098 hci_cc_write_local_name(hdev, skb);
2099 break;
2100
2101 case HCI_OP_READ_LOCAL_NAME:
2102 hci_cc_read_local_name(hdev, skb);
2103 break;
2104
2105 case HCI_OP_WRITE_AUTH_ENABLE:
2106 hci_cc_write_auth_enable(hdev, skb);
2107 break;
2108
2109 case HCI_OP_WRITE_ENCRYPT_MODE:
2110 hci_cc_write_encrypt_mode(hdev, skb);
2111 break;
2112
2113 case HCI_OP_WRITE_SCAN_ENABLE:
2114 hci_cc_write_scan_enable(hdev, skb);
2115 break;
2116
2117 case HCI_OP_READ_CLASS_OF_DEV:
2118 hci_cc_read_class_of_dev(hdev, skb);
2119 break;
2120
2121 case HCI_OP_WRITE_CLASS_OF_DEV:
2122 hci_cc_write_class_of_dev(hdev, skb);
2123 break;
2124
2125 case HCI_OP_READ_VOICE_SETTING:
2126 hci_cc_read_voice_setting(hdev, skb);
2127 break;
2128
2129 case HCI_OP_WRITE_VOICE_SETTING:
2130 hci_cc_write_voice_setting(hdev, skb);
2131 break;
2132
2133 case HCI_OP_HOST_BUFFER_SIZE:
2134 hci_cc_host_buffer_size(hdev, skb);
2135 break;
2136
Marcel Holtmann333140b2008-07-14 20:13:48 +02002137 case HCI_OP_READ_SSP_MODE:
2138 hci_cc_read_ssp_mode(hdev, skb);
2139 break;
2140
2141 case HCI_OP_WRITE_SSP_MODE:
2142 hci_cc_write_ssp_mode(hdev, skb);
2143 break;
2144
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002145 case HCI_OP_READ_LOCAL_VERSION:
2146 hci_cc_read_local_version(hdev, skb);
2147 break;
2148
2149 case HCI_OP_READ_LOCAL_COMMANDS:
2150 hci_cc_read_local_commands(hdev, skb);
2151 break;
2152
2153 case HCI_OP_READ_LOCAL_FEATURES:
2154 hci_cc_read_local_features(hdev, skb);
2155 break;
2156
Andre Guedes971e3a42011-06-30 19:20:52 -03002157 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2158 hci_cc_read_local_ext_features(hdev, skb);
2159 break;
2160
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002161 case HCI_OP_READ_BUFFER_SIZE:
2162 hci_cc_read_buffer_size(hdev, skb);
2163 break;
2164
2165 case HCI_OP_READ_BD_ADDR:
2166 hci_cc_read_bd_addr(hdev, skb);
2167 break;
2168
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002169 case HCI_OP_READ_DATA_BLOCK_SIZE:
2170 hci_cc_read_data_block_size(hdev, skb);
2171 break;
2172
Johan Hedberg23bb5762010-12-21 23:01:27 +02002173 case HCI_OP_WRITE_CA_TIMEOUT:
2174 hci_cc_write_ca_timeout(hdev, skb);
2175 break;
2176
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002177 case HCI_OP_READ_FLOW_CONTROL_MODE:
2178 hci_cc_read_flow_control_mode(hdev, skb);
2179 break;
2180
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002181 case HCI_OP_READ_LOCAL_AMP_INFO:
2182 hci_cc_read_local_amp_info(hdev, skb);
2183 break;
2184
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002185 case HCI_OP_DELETE_STORED_LINK_KEY:
2186 hci_cc_delete_stored_link_key(hdev, skb);
2187 break;
2188
Johan Hedbergd5859e22011-01-25 01:19:58 +02002189 case HCI_OP_SET_EVENT_MASK:
2190 hci_cc_set_event_mask(hdev, skb);
2191 break;
2192
2193 case HCI_OP_WRITE_INQUIRY_MODE:
2194 hci_cc_write_inquiry_mode(hdev, skb);
2195 break;
2196
2197 case HCI_OP_READ_INQ_RSP_TX_POWER:
2198 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2199 break;
2200
2201 case HCI_OP_SET_EVENT_FLT:
2202 hci_cc_set_event_flt(hdev, skb);
2203 break;
2204
Johan Hedberg980e1a52011-01-22 06:10:07 +02002205 case HCI_OP_PIN_CODE_REPLY:
2206 hci_cc_pin_code_reply(hdev, skb);
2207 break;
2208
2209 case HCI_OP_PIN_CODE_NEG_REPLY:
2210 hci_cc_pin_code_neg_reply(hdev, skb);
2211 break;
2212
Szymon Jancc35938b2011-03-22 13:12:21 +01002213 case HCI_OP_READ_LOCAL_OOB_DATA:
2214 hci_cc_read_local_oob_data_reply(hdev, skb);
2215 break;
2216
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002217 case HCI_OP_LE_READ_BUFFER_SIZE:
2218 hci_cc_le_read_buffer_size(hdev, skb);
2219 break;
2220
Johan Hedberga5c29682011-02-19 12:05:57 -03002221 case HCI_OP_USER_CONFIRM_REPLY:
2222 hci_cc_user_confirm_reply(hdev, skb);
2223 break;
2224
2225 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2226 hci_cc_user_confirm_neg_reply(hdev, skb);
2227 break;
2228
Brian Gix1143d452011-11-23 08:28:34 -08002229 case HCI_OP_USER_PASSKEY_REPLY:
2230 hci_cc_user_passkey_reply(hdev, skb);
2231 break;
2232
2233 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2234 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002235
2236 case HCI_OP_LE_SET_SCAN_PARAM:
2237 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002238 break;
2239
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002240 case HCI_OP_LE_SET_SCAN_ENABLE:
2241 hci_cc_le_set_scan_enable(hdev, skb);
2242 break;
2243
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002244 case HCI_OP_LE_LTK_REPLY:
2245 hci_cc_le_ltk_reply(hdev, skb);
2246 break;
2247
2248 case HCI_OP_LE_LTK_NEG_REPLY:
2249 hci_cc_le_ltk_neg_reply(hdev, skb);
2250 break;
2251
Andre Guedesf9b49302011-06-30 19:20:53 -03002252 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2253 hci_cc_write_le_host_supported(hdev, skb);
2254 break;
2255
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002256 default:
2257 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2258 break;
2259 }
2260
Ville Tervo6bd32322011-02-16 16:32:41 +02002261 if (ev->opcode != HCI_OP_NOP)
2262 del_timer(&hdev->cmd_timer);
2263
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002264 if (ev->ncmd) {
2265 atomic_set(&hdev->cmd_cnt, 1);
2266 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002267 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002268 }
2269}
2270
2271static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2272{
2273 struct hci_ev_cmd_status *ev = (void *) skb->data;
2274 __u16 opcode;
2275
2276 skb_pull(skb, sizeof(*ev));
2277
2278 opcode = __le16_to_cpu(ev->opcode);
2279
2280 switch (opcode) {
2281 case HCI_OP_INQUIRY:
2282 hci_cs_inquiry(hdev, ev->status);
2283 break;
2284
2285 case HCI_OP_CREATE_CONN:
2286 hci_cs_create_conn(hdev, ev->status);
2287 break;
2288
2289 case HCI_OP_ADD_SCO:
2290 hci_cs_add_sco(hdev, ev->status);
2291 break;
2292
Marcel Holtmannf8558552008-07-14 20:13:49 +02002293 case HCI_OP_AUTH_REQUESTED:
2294 hci_cs_auth_requested(hdev, ev->status);
2295 break;
2296
2297 case HCI_OP_SET_CONN_ENCRYPT:
2298 hci_cs_set_conn_encrypt(hdev, ev->status);
2299 break;
2300
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002301 case HCI_OP_REMOTE_NAME_REQ:
2302 hci_cs_remote_name_req(hdev, ev->status);
2303 break;
2304
Marcel Holtmann769be972008-07-14 20:13:49 +02002305 case HCI_OP_READ_REMOTE_FEATURES:
2306 hci_cs_read_remote_features(hdev, ev->status);
2307 break;
2308
2309 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2310 hci_cs_read_remote_ext_features(hdev, ev->status);
2311 break;
2312
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002313 case HCI_OP_SETUP_SYNC_CONN:
2314 hci_cs_setup_sync_conn(hdev, ev->status);
2315 break;
2316
2317 case HCI_OP_SNIFF_MODE:
2318 hci_cs_sniff_mode(hdev, ev->status);
2319 break;
2320
2321 case HCI_OP_EXIT_SNIFF_MODE:
2322 hci_cs_exit_sniff_mode(hdev, ev->status);
2323 break;
2324
Johan Hedberg8962ee72011-01-20 12:40:27 +02002325 case HCI_OP_DISCONNECT:
2326 if (ev->status != 0)
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002327 mgmt_disconnect_failed(hdev, NULL, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002328 break;
2329
Ville Tervofcd89c02011-02-10 22:38:47 -03002330 case HCI_OP_LE_CREATE_CONN:
2331 hci_cs_le_create_conn(hdev, ev->status);
2332 break;
2333
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002334 case HCI_OP_LE_START_ENC:
2335 hci_cs_le_start_enc(hdev, ev->status);
2336 break;
2337
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002338 default:
2339 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2340 break;
2341 }
2342
Ville Tervo6bd32322011-02-16 16:32:41 +02002343 if (ev->opcode != HCI_OP_NOP)
2344 del_timer(&hdev->cmd_timer);
2345
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002346 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002347 atomic_set(&hdev->cmd_cnt, 1);
2348 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002349 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002350 }
2351}
2352
2353static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2354{
2355 struct hci_ev_role_change *ev = (void *) skb->data;
2356 struct hci_conn *conn;
2357
2358 BT_DBG("%s status %d", hdev->name, ev->status);
2359
2360 hci_dev_lock(hdev);
2361
2362 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2363 if (conn) {
2364 if (!ev->status) {
2365 if (ev->role)
2366 conn->link_mode &= ~HCI_LM_MASTER;
2367 else
2368 conn->link_mode |= HCI_LM_MASTER;
2369 }
2370
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002371 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002372
2373 hci_role_switch_cfm(conn, ev->status, ev->role);
2374 }
2375
2376 hci_dev_unlock(hdev);
2377}
2378
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2380{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002381 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382 int i;
2383
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002384 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2385 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2386 return;
2387 }
2388
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002389 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2390 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002391 BT_DBG("%s bad parameters", hdev->name);
2392 return;
2393 }
2394
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002395 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2396
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002397 for (i = 0; i < ev->num_hndl; i++) {
2398 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399 struct hci_conn *conn;
2400 __u16 handle, count;
2401
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002402 handle = __le16_to_cpu(info->handle);
2403 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404
2405 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002406 if (!conn)
2407 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002409 conn->sent -= count;
2410
2411 switch (conn->type) {
2412 case ACL_LINK:
2413 hdev->acl_cnt += count;
2414 if (hdev->acl_cnt > hdev->acl_pkts)
2415 hdev->acl_cnt = hdev->acl_pkts;
2416 break;
2417
2418 case LE_LINK:
2419 if (hdev->le_pkts) {
2420 hdev->le_cnt += count;
2421 if (hdev->le_cnt > hdev->le_pkts)
2422 hdev->le_cnt = hdev->le_pkts;
2423 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002424 hdev->acl_cnt += count;
2425 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002426 hdev->acl_cnt = hdev->acl_pkts;
2427 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002428 break;
2429
2430 case SCO_LINK:
2431 hdev->sco_cnt += count;
2432 if (hdev->sco_cnt > hdev->sco_pkts)
2433 hdev->sco_cnt = hdev->sco_pkts;
2434 break;
2435
2436 default:
2437 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2438 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439 }
2440 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002441
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002442 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002443}
2444
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002445static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2446 struct sk_buff *skb)
2447{
2448 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2449 int i;
2450
2451 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2452 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2453 return;
2454 }
2455
2456 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2457 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2458 BT_DBG("%s bad parameters", hdev->name);
2459 return;
2460 }
2461
2462 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2463 ev->num_hndl);
2464
2465 for (i = 0; i < ev->num_hndl; i++) {
2466 struct hci_comp_blocks_info *info = &ev->handles[i];
2467 struct hci_conn *conn;
2468 __u16 handle, block_count;
2469
2470 handle = __le16_to_cpu(info->handle);
2471 block_count = __le16_to_cpu(info->blocks);
2472
2473 conn = hci_conn_hash_lookup_handle(hdev, handle);
2474 if (!conn)
2475 continue;
2476
2477 conn->sent -= block_count;
2478
2479 switch (conn->type) {
2480 case ACL_LINK:
2481 hdev->block_cnt += block_count;
2482 if (hdev->block_cnt > hdev->num_blocks)
2483 hdev->block_cnt = hdev->num_blocks;
2484 break;
2485
2486 default:
2487 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2488 break;
2489 }
2490 }
2491
2492 queue_work(hdev->workqueue, &hdev->tx_work);
2493}
2494
Marcel Holtmann04837f62006-07-03 10:02:33 +02002495static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002497 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002498 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499
2500 BT_DBG("%s status %d", hdev->name, ev->status);
2501
2502 hci_dev_lock(hdev);
2503
Marcel Holtmann04837f62006-07-03 10:02:33 +02002504 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2505 if (conn) {
2506 conn->mode = ev->mode;
2507 conn->interval = __le16_to_cpu(ev->interval);
2508
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002509 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002510 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002511 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002512 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002513 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002514 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002515
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002516 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002517 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002518 }
2519
2520 hci_dev_unlock(hdev);
2521}
2522
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2524{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002525 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2526 struct hci_conn *conn;
2527
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002528 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002529
2530 hci_dev_lock(hdev);
2531
2532 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002533 if (!conn)
2534 goto unlock;
2535
2536 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002537 hci_conn_hold(conn);
2538 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2539 hci_conn_put(conn);
2540 }
2541
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002542 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002543 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2544 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002545 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002546 u8 secure;
2547
2548 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2549 secure = 1;
2550 else
2551 secure = 0;
2552
Johan Hedberg744cf192011-11-08 20:40:14 +02002553 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002554 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002555
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002556unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002557 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558}
2559
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2561{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002562 struct hci_ev_link_key_req *ev = (void *) skb->data;
2563 struct hci_cp_link_key_reply cp;
2564 struct hci_conn *conn;
2565 struct link_key *key;
2566
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002567 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002568
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002569 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002570 return;
2571
2572 hci_dev_lock(hdev);
2573
2574 key = hci_find_link_key(hdev, &ev->bdaddr);
2575 if (!key) {
2576 BT_DBG("%s link key not found for %s", hdev->name,
2577 batostr(&ev->bdaddr));
2578 goto not_found;
2579 }
2580
2581 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2582 batostr(&ev->bdaddr));
2583
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002584 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002585 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002586 BT_DBG("%s ignoring debug key", hdev->name);
2587 goto not_found;
2588 }
2589
2590 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002591 if (conn) {
2592 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2593 conn->auth_type != 0xff &&
2594 (conn->auth_type & 0x01)) {
2595 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2596 goto not_found;
2597 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002598
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002599 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2600 conn->pending_sec_level == BT_SECURITY_HIGH) {
2601 BT_DBG("%s ignoring key unauthenticated for high \
2602 security", hdev->name);
2603 goto not_found;
2604 }
2605
2606 conn->key_type = key->type;
2607 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002608 }
2609
2610 bacpy(&cp.bdaddr, &ev->bdaddr);
2611 memcpy(cp.link_key, key->val, 16);
2612
2613 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2614
2615 hci_dev_unlock(hdev);
2616
2617 return;
2618
2619not_found:
2620 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2621 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622}
2623
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2625{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002626 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2627 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002628 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002629
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002630 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002631
2632 hci_dev_lock(hdev);
2633
2634 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2635 if (conn) {
2636 hci_conn_hold(conn);
2637 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002638 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002639
2640 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2641 conn->key_type = ev->key_type;
2642
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002643 hci_conn_put(conn);
2644 }
2645
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002646 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002647 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002648 ev->key_type, pin_len);
2649
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002650 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002651}
2652
Marcel Holtmann04837f62006-07-03 10:02:33 +02002653static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2654{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002655 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002656 struct hci_conn *conn;
2657
2658 BT_DBG("%s status %d", hdev->name, ev->status);
2659
2660 hci_dev_lock(hdev);
2661
2662 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663 if (conn && !ev->status) {
2664 struct inquiry_entry *ie;
2665
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002666 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2667 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668 ie->data.clock_offset = ev->clock_offset;
2669 ie->timestamp = jiffies;
2670 }
2671 }
2672
2673 hci_dev_unlock(hdev);
2674}
2675
Marcel Holtmanna8746412008-07-14 20:13:46 +02002676static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2677{
2678 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2679 struct hci_conn *conn;
2680
2681 BT_DBG("%s status %d", hdev->name, ev->status);
2682
2683 hci_dev_lock(hdev);
2684
2685 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2686 if (conn && !ev->status)
2687 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2688
2689 hci_dev_unlock(hdev);
2690}
2691
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002692static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2693{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002694 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002695 struct inquiry_entry *ie;
2696
2697 BT_DBG("%s", hdev->name);
2698
2699 hci_dev_lock(hdev);
2700
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002701 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2702 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002703 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2704 ie->timestamp = jiffies;
2705 }
2706
2707 hci_dev_unlock(hdev);
2708}
2709
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002710static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2711{
2712 struct inquiry_data data;
2713 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg31754052012-01-04 13:39:52 +02002714 bool name_known;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002715
2716 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2717
2718 if (!num_rsp)
2719 return;
2720
2721 hci_dev_lock(hdev);
2722
2723 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002724 struct inquiry_info_with_rssi_and_pscan_mode *info;
2725 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002726
Johan Hedberge17acd42011-03-30 23:57:16 +03002727 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002728 bacpy(&data.bdaddr, &info->bdaddr);
2729 data.pscan_rep_mode = info->pscan_rep_mode;
2730 data.pscan_period_mode = info->pscan_period_mode;
2731 data.pscan_mode = info->pscan_mode;
2732 memcpy(data.dev_class, info->dev_class, 3);
2733 data.clock_offset = info->clock_offset;
2734 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002735 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002736
2737 name_known = hci_inquiry_cache_update(hdev, &data,
2738 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002739 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002740 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002741 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002742 }
2743 } else {
2744 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2745
Johan Hedberge17acd42011-03-30 23:57:16 +03002746 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002747 bacpy(&data.bdaddr, &info->bdaddr);
2748 data.pscan_rep_mode = info->pscan_rep_mode;
2749 data.pscan_period_mode = info->pscan_period_mode;
2750 data.pscan_mode = 0x00;
2751 memcpy(data.dev_class, info->dev_class, 3);
2752 data.clock_offset = info->clock_offset;
2753 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002754 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002755 name_known = hci_inquiry_cache_update(hdev, &data,
2756 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002757 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002758 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002759 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002760 }
2761 }
2762
2763 hci_dev_unlock(hdev);
2764}
2765
2766static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2767{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002768 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2769 struct hci_conn *conn;
2770
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002771 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002772
Marcel Holtmann41a96212008-07-14 20:13:48 +02002773 hci_dev_lock(hdev);
2774
2775 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002776 if (!conn)
2777 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002778
Johan Hedbergccd556f2010-11-10 17:11:51 +02002779 if (!ev->status && ev->page == 0x01) {
2780 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002781
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002782 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2783 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002784 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002785
Johan Hedberg58a681e2012-01-16 06:47:28 +02002786 if (ev->features[0] & 0x01)
2787 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002788 }
2789
Johan Hedbergccd556f2010-11-10 17:11:51 +02002790 if (conn->state != BT_CONFIG)
2791 goto unlock;
2792
Johan Hedberg127178d2010-11-18 22:22:29 +02002793 if (!ev->status) {
2794 struct hci_cp_remote_name_req cp;
2795 memset(&cp, 0, sizeof(cp));
2796 bacpy(&cp.bdaddr, &conn->dst);
2797 cp.pscan_rep_mode = 0x02;
2798 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002799 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2800 mgmt_device_connected(hdev, &conn->dst, conn->type,
2801 conn->dst_type, NULL, 0,
2802 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002803
Johan Hedberg127178d2010-11-18 22:22:29 +02002804 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002805 conn->state = BT_CONNECTED;
2806 hci_proto_connect_cfm(conn, ev->status);
2807 hci_conn_put(conn);
2808 }
2809
2810unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002811 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002812}
2813
2814static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2815{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002816 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2817 struct hci_conn *conn;
2818
2819 BT_DBG("%s status %d", hdev->name, ev->status);
2820
2821 hci_dev_lock(hdev);
2822
2823 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002824 if (!conn) {
2825 if (ev->link_type == ESCO_LINK)
2826 goto unlock;
2827
2828 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2829 if (!conn)
2830 goto unlock;
2831
2832 conn->type = SCO_LINK;
2833 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002834
Marcel Holtmann732547f2009-04-19 19:14:14 +02002835 switch (ev->status) {
2836 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002837 conn->handle = __le16_to_cpu(ev->handle);
2838 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002839
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002840 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002841 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002842 break;
2843
Stephen Coe705e5712010-02-16 11:29:44 -05002844 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002845 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002846 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002847 case 0x1f: /* Unspecified error */
2848 if (conn->out && conn->attempt < 2) {
2849 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2850 (hdev->esco_type & EDR_ESCO_MASK);
2851 hci_setup_sync(conn, conn->link->handle);
2852 goto unlock;
2853 }
2854 /* fall through */
2855
2856 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002857 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002858 break;
2859 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002860
2861 hci_proto_connect_cfm(conn, ev->status);
2862 if (ev->status)
2863 hci_conn_del(conn);
2864
2865unlock:
2866 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002867}
2868
2869static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2870{
2871 BT_DBG("%s", hdev->name);
2872}
2873
Marcel Holtmann04837f62006-07-03 10:02:33 +02002874static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2875{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002876 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002877
2878 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002879}
2880
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002881static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2882{
2883 struct inquiry_data data;
2884 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2885 int num_rsp = *((__u8 *) skb->data);
2886
2887 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2888
2889 if (!num_rsp)
2890 return;
2891
2892 hci_dev_lock(hdev);
2893
Johan Hedberge17acd42011-03-30 23:57:16 +03002894 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg561aafb2012-01-04 13:31:59 +02002895 bool name_known;
2896
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002897 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002898 data.pscan_rep_mode = info->pscan_rep_mode;
2899 data.pscan_period_mode = info->pscan_period_mode;
2900 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002901 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002902 data.clock_offset = info->clock_offset;
2903 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002904 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002905
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002906 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002907 name_known = eir_has_data_type(info->data,
2908 sizeof(info->data),
2909 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002910 else
2911 name_known = true;
2912
Johan Hedberg31754052012-01-04 13:39:52 +02002913 name_known = hci_inquiry_cache_update(hdev, &data, name_known);
Johan Hedberg48264f02011-11-09 13:58:58 +02002914 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002915 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002916 !name_known, info->data,
2917 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002918 }
2919
2920 hci_dev_unlock(hdev);
2921}
2922
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002923static inline u8 hci_get_auth_req(struct hci_conn *conn)
2924{
2925 /* If remote requests dedicated bonding follow that lead */
2926 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2927 /* If both remote and local IO capabilities allow MITM
2928 * protection then require it, otherwise don't */
2929 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2930 return 0x02;
2931 else
2932 return 0x03;
2933 }
2934
2935 /* If remote requests no-bonding follow that lead */
2936 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002937 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002938
2939 return conn->auth_type;
2940}
2941
Marcel Holtmann04936842008-07-14 20:13:48 +02002942static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2943{
2944 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2945 struct hci_conn *conn;
2946
2947 BT_DBG("%s", hdev->name);
2948
2949 hci_dev_lock(hdev);
2950
2951 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002952 if (!conn)
2953 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002954
Johan Hedberg03b555e2011-01-04 15:40:05 +02002955 hci_conn_hold(conn);
2956
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002957 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002958 goto unlock;
2959
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002960 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02002961 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002962 struct hci_cp_io_capability_reply cp;
2963
2964 bacpy(&cp.bdaddr, &ev->bdaddr);
2965 cp.capability = conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07002966 conn->auth_type = hci_get_auth_req(conn);
2967 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002968
Johan Hedberg58a681e2012-01-16 06:47:28 +02002969 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01002970 hci_find_remote_oob_data(hdev, &conn->dst))
2971 cp.oob_data = 0x01;
2972 else
2973 cp.oob_data = 0x00;
2974
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002975 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2976 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002977 } else {
2978 struct hci_cp_io_capability_neg_reply cp;
2979
2980 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002981 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02002982
2983 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2984 sizeof(cp), &cp);
2985 }
2986
2987unlock:
2988 hci_dev_unlock(hdev);
2989}
2990
2991static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2992{
2993 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2994 struct hci_conn *conn;
2995
2996 BT_DBG("%s", hdev->name);
2997
2998 hci_dev_lock(hdev);
2999
3000 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3001 if (!conn)
3002 goto unlock;
3003
Johan Hedberg03b555e2011-01-04 15:40:05 +02003004 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003005 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003006 if (ev->oob_data)
3007 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003008
3009unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003010 hci_dev_unlock(hdev);
3011}
3012
Johan Hedberga5c29682011-02-19 12:05:57 -03003013static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3014 struct sk_buff *skb)
3015{
3016 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003017 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003018 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003019
3020 BT_DBG("%s", hdev->name);
3021
3022 hci_dev_lock(hdev);
3023
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003024 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003025 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003026
Johan Hedberg7a828902011-04-28 11:28:53 -07003027 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3028 if (!conn)
3029 goto unlock;
3030
3031 loc_mitm = (conn->auth_type & 0x01);
3032 rem_mitm = (conn->remote_auth & 0x01);
3033
3034 /* If we require MITM but the remote device can't provide that
3035 * (it has NoInputNoOutput) then reject the confirmation
3036 * request. The only exception is when we're dedicated bonding
3037 * initiators (connect_cfm_cb set) since then we always have the MITM
3038 * bit set. */
3039 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3040 BT_DBG("Rejecting request: remote device can't provide MITM");
3041 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3042 sizeof(ev->bdaddr), &ev->bdaddr);
3043 goto unlock;
3044 }
3045
3046 /* If no side requires MITM protection; auto-accept */
3047 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3048 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003049
3050 /* If we're not the initiators request authorization to
3051 * proceed from user space (mgmt_user_confirm with
3052 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003053 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003054 BT_DBG("Confirming auto-accept as acceptor");
3055 confirm_hint = 1;
3056 goto confirm;
3057 }
3058
Johan Hedberg9f616562011-04-28 11:28:54 -07003059 BT_DBG("Auto-accept of user confirmation with %ums delay",
3060 hdev->auto_accept_delay);
3061
3062 if (hdev->auto_accept_delay > 0) {
3063 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3064 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3065 goto unlock;
3066 }
3067
Johan Hedberg7a828902011-04-28 11:28:53 -07003068 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3069 sizeof(ev->bdaddr), &ev->bdaddr);
3070 goto unlock;
3071 }
3072
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003073confirm:
Johan Hedberg744cf192011-11-08 20:40:14 +02003074 mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003075 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003076
3077unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003078 hci_dev_unlock(hdev);
3079}
3080
Brian Gix1143d452011-11-23 08:28:34 -08003081static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3082 struct sk_buff *skb)
3083{
3084 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3085
3086 BT_DBG("%s", hdev->name);
3087
3088 hci_dev_lock(hdev);
3089
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003090 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08003091 mgmt_user_passkey_request(hdev, &ev->bdaddr);
3092
3093 hci_dev_unlock(hdev);
3094}
3095
Marcel Holtmann04936842008-07-14 20:13:48 +02003096static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3097{
3098 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3099 struct hci_conn *conn;
3100
3101 BT_DBG("%s", hdev->name);
3102
3103 hci_dev_lock(hdev);
3104
3105 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003106 if (!conn)
3107 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003108
Johan Hedberg2a611692011-02-19 12:06:00 -03003109 /* To avoid duplicate auth_failed events to user space we check
3110 * the HCI_CONN_AUTH_PEND flag which will be set if we
3111 * initiated the authentication. A traditional auth_complete
3112 * event gets always produced as initiator and is also mapped to
3113 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003114 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedberg744cf192011-11-08 20:40:14 +02003115 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003116
3117 hci_conn_put(conn);
3118
3119unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003120 hci_dev_unlock(hdev);
3121}
3122
Marcel Holtmann41a96212008-07-14 20:13:48 +02003123static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3124{
3125 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3126 struct inquiry_entry *ie;
3127
3128 BT_DBG("%s", hdev->name);
3129
3130 hci_dev_lock(hdev);
3131
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003132 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3133 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003134 ie->data.ssp_mode = (ev->features[0] & 0x01);
3135
3136 hci_dev_unlock(hdev);
3137}
3138
Szymon Janc2763eda2011-03-22 13:12:22 +01003139static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3140 struct sk_buff *skb)
3141{
3142 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3143 struct oob_data *data;
3144
3145 BT_DBG("%s", hdev->name);
3146
3147 hci_dev_lock(hdev);
3148
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003149 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003150 goto unlock;
3151
Szymon Janc2763eda2011-03-22 13:12:22 +01003152 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3153 if (data) {
3154 struct hci_cp_remote_oob_data_reply cp;
3155
3156 bacpy(&cp.bdaddr, &ev->bdaddr);
3157 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3158 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3159
3160 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3161 &cp);
3162 } else {
3163 struct hci_cp_remote_oob_data_neg_reply cp;
3164
3165 bacpy(&cp.bdaddr, &ev->bdaddr);
3166 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3167 &cp);
3168 }
3169
Szymon Jance1ba1f12011-04-06 13:01:59 +02003170unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003171 hci_dev_unlock(hdev);
3172}
3173
Ville Tervofcd89c02011-02-10 22:38:47 -03003174static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3175{
3176 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3177 struct hci_conn *conn;
3178
3179 BT_DBG("%s status %d", hdev->name, ev->status);
3180
3181 hci_dev_lock(hdev);
3182
3183 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003184 if (!conn) {
3185 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3186 if (!conn) {
3187 BT_ERR("No memory for new connection");
3188 hci_dev_unlock(hdev);
3189 return;
3190 }
Andre Guedes29b79882011-05-31 14:20:54 -03003191
3192 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003193 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003194
3195 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003196 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3197 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003198 hci_proto_connect_cfm(conn, ev->status);
3199 conn->state = BT_CLOSED;
3200 hci_conn_del(conn);
3201 goto unlock;
3202 }
3203
Johan Hedbergb644ba32012-01-17 21:48:47 +02003204 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3205 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3206 conn->dst_type, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003207
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003208 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003209 conn->handle = __le16_to_cpu(ev->handle);
3210 conn->state = BT_CONNECTED;
3211
3212 hci_conn_hold_device(conn);
3213 hci_conn_add_sysfs(conn);
3214
3215 hci_proto_connect_cfm(conn, ev->status);
3216
3217unlock:
3218 hci_dev_unlock(hdev);
3219}
3220
Andre Guedes9aa04c92011-05-26 16:23:51 -03003221static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3222 struct sk_buff *skb)
3223{
Andre Guedese95beb42011-09-26 20:48:35 -03003224 u8 num_reports = skb->data[0];
3225 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003226 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003227
3228 hci_dev_lock(hdev);
3229
Andre Guedese95beb42011-09-26 20:48:35 -03003230 while (num_reports--) {
3231 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003232
Andre Guedes9aa04c92011-05-26 16:23:51 -03003233 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003234
Andre Guedes3c9e9192012-01-10 18:20:50 -03003235 rssi = ev->data[ev->length];
3236 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3237 NULL, rssi, 0, ev->data, ev->length);
3238
Andre Guedese95beb42011-09-26 20:48:35 -03003239 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003240 }
3241
3242 hci_dev_unlock(hdev);
3243}
3244
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003245static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3246 struct sk_buff *skb)
3247{
3248 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3249 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003250 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003251 struct hci_conn *conn;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003252 struct link_key *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003253
3254 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3255
3256 hci_dev_lock(hdev);
3257
3258 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003259 if (conn == NULL)
3260 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003261
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003262 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3263 if (ltk == NULL)
3264 goto not_found;
3265
3266 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003267 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes726b4ff2011-07-08 18:31:45 -03003268 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003269
3270 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3271
3272 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003273
3274 return;
3275
3276not_found:
3277 neg.handle = ev->handle;
3278 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3279 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003280}
3281
Ville Tervofcd89c02011-02-10 22:38:47 -03003282static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3283{
3284 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3285
3286 skb_pull(skb, sizeof(*le_ev));
3287
3288 switch (le_ev->subevent) {
3289 case HCI_EV_LE_CONN_COMPLETE:
3290 hci_le_conn_complete_evt(hdev, skb);
3291 break;
3292
Andre Guedes9aa04c92011-05-26 16:23:51 -03003293 case HCI_EV_LE_ADVERTISING_REPORT:
3294 hci_le_adv_report_evt(hdev, skb);
3295 break;
3296
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003297 case HCI_EV_LE_LTK_REQ:
3298 hci_le_ltk_request_evt(hdev, skb);
3299 break;
3300
Ville Tervofcd89c02011-02-10 22:38:47 -03003301 default:
3302 break;
3303 }
3304}
3305
Linus Torvalds1da177e2005-04-16 15:20:36 -07003306void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3307{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003308 struct hci_event_hdr *hdr = (void *) skb->data;
3309 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003310
3311 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3312
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003313 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003314 case HCI_EV_INQUIRY_COMPLETE:
3315 hci_inquiry_complete_evt(hdev, skb);
3316 break;
3317
3318 case HCI_EV_INQUIRY_RESULT:
3319 hci_inquiry_result_evt(hdev, skb);
3320 break;
3321
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003322 case HCI_EV_CONN_COMPLETE:
3323 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003324 break;
3325
Linus Torvalds1da177e2005-04-16 15:20:36 -07003326 case HCI_EV_CONN_REQUEST:
3327 hci_conn_request_evt(hdev, skb);
3328 break;
3329
Linus Torvalds1da177e2005-04-16 15:20:36 -07003330 case HCI_EV_DISCONN_COMPLETE:
3331 hci_disconn_complete_evt(hdev, skb);
3332 break;
3333
Linus Torvalds1da177e2005-04-16 15:20:36 -07003334 case HCI_EV_AUTH_COMPLETE:
3335 hci_auth_complete_evt(hdev, skb);
3336 break;
3337
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003338 case HCI_EV_REMOTE_NAME:
3339 hci_remote_name_evt(hdev, skb);
3340 break;
3341
Linus Torvalds1da177e2005-04-16 15:20:36 -07003342 case HCI_EV_ENCRYPT_CHANGE:
3343 hci_encrypt_change_evt(hdev, skb);
3344 break;
3345
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003346 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3347 hci_change_link_key_complete_evt(hdev, skb);
3348 break;
3349
3350 case HCI_EV_REMOTE_FEATURES:
3351 hci_remote_features_evt(hdev, skb);
3352 break;
3353
3354 case HCI_EV_REMOTE_VERSION:
3355 hci_remote_version_evt(hdev, skb);
3356 break;
3357
3358 case HCI_EV_QOS_SETUP_COMPLETE:
3359 hci_qos_setup_complete_evt(hdev, skb);
3360 break;
3361
3362 case HCI_EV_CMD_COMPLETE:
3363 hci_cmd_complete_evt(hdev, skb);
3364 break;
3365
3366 case HCI_EV_CMD_STATUS:
3367 hci_cmd_status_evt(hdev, skb);
3368 break;
3369
3370 case HCI_EV_ROLE_CHANGE:
3371 hci_role_change_evt(hdev, skb);
3372 break;
3373
3374 case HCI_EV_NUM_COMP_PKTS:
3375 hci_num_comp_pkts_evt(hdev, skb);
3376 break;
3377
3378 case HCI_EV_MODE_CHANGE:
3379 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003380 break;
3381
3382 case HCI_EV_PIN_CODE_REQ:
3383 hci_pin_code_request_evt(hdev, skb);
3384 break;
3385
3386 case HCI_EV_LINK_KEY_REQ:
3387 hci_link_key_request_evt(hdev, skb);
3388 break;
3389
3390 case HCI_EV_LINK_KEY_NOTIFY:
3391 hci_link_key_notify_evt(hdev, skb);
3392 break;
3393
3394 case HCI_EV_CLOCK_OFFSET:
3395 hci_clock_offset_evt(hdev, skb);
3396 break;
3397
Marcel Holtmanna8746412008-07-14 20:13:46 +02003398 case HCI_EV_PKT_TYPE_CHANGE:
3399 hci_pkt_type_change_evt(hdev, skb);
3400 break;
3401
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003402 case HCI_EV_PSCAN_REP_MODE:
3403 hci_pscan_rep_mode_evt(hdev, skb);
3404 break;
3405
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003406 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3407 hci_inquiry_result_with_rssi_evt(hdev, skb);
3408 break;
3409
3410 case HCI_EV_REMOTE_EXT_FEATURES:
3411 hci_remote_ext_features_evt(hdev, skb);
3412 break;
3413
3414 case HCI_EV_SYNC_CONN_COMPLETE:
3415 hci_sync_conn_complete_evt(hdev, skb);
3416 break;
3417
3418 case HCI_EV_SYNC_CONN_CHANGED:
3419 hci_sync_conn_changed_evt(hdev, skb);
3420 break;
3421
Marcel Holtmann04837f62006-07-03 10:02:33 +02003422 case HCI_EV_SNIFF_SUBRATE:
3423 hci_sniff_subrate_evt(hdev, skb);
3424 break;
3425
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003426 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3427 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003428 break;
3429
Marcel Holtmann04936842008-07-14 20:13:48 +02003430 case HCI_EV_IO_CAPA_REQUEST:
3431 hci_io_capa_request_evt(hdev, skb);
3432 break;
3433
Johan Hedberg03b555e2011-01-04 15:40:05 +02003434 case HCI_EV_IO_CAPA_REPLY:
3435 hci_io_capa_reply_evt(hdev, skb);
3436 break;
3437
Johan Hedberga5c29682011-02-19 12:05:57 -03003438 case HCI_EV_USER_CONFIRM_REQUEST:
3439 hci_user_confirm_request_evt(hdev, skb);
3440 break;
3441
Brian Gix1143d452011-11-23 08:28:34 -08003442 case HCI_EV_USER_PASSKEY_REQUEST:
3443 hci_user_passkey_request_evt(hdev, skb);
3444 break;
3445
Marcel Holtmann04936842008-07-14 20:13:48 +02003446 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3447 hci_simple_pair_complete_evt(hdev, skb);
3448 break;
3449
Marcel Holtmann41a96212008-07-14 20:13:48 +02003450 case HCI_EV_REMOTE_HOST_FEATURES:
3451 hci_remote_host_features_evt(hdev, skb);
3452 break;
3453
Ville Tervofcd89c02011-02-10 22:38:47 -03003454 case HCI_EV_LE_META:
3455 hci_le_meta_evt(hdev, skb);
3456 break;
3457
Szymon Janc2763eda2011-03-22 13:12:22 +01003458 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3459 hci_remote_oob_data_request_evt(hdev, skb);
3460 break;
3461
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003462 case HCI_EV_NUM_COMP_BLOCKS:
3463 hci_num_comp_blocks_evt(hdev, skb);
3464 break;
3465
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003466 default:
3467 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003468 break;
3469 }
3470
3471 kfree_skb(skb);
3472 hdev->stat.evt_rx++;
3473}
3474
3475/* Generate internal stack event */
3476void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3477{
3478 struct hci_event_hdr *hdr;
3479 struct hci_ev_stack_internal *ev;
3480 struct sk_buff *skb;
3481
3482 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3483 if (!skb)
3484 return;
3485
3486 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3487 hdr->evt = HCI_EV_STACK_INTERNAL;
3488 hdr->plen = sizeof(*ev) + dlen;
3489
3490 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3491 ev->type = type;
3492 memcpy(ev->data, data, dlen);
3493
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003494 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003495 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003496
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003497 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003498 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003499 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003500 kfree_skb(skb);
3501}
Andre Guedese6100a22011-06-30 19:20:54 -03003502
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003503module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003504MODULE_PARM_DESC(enable_le, "Enable LE support");