blob: f3dafae6e1db1efffd42ca6366555931459f596a [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 Hedberg44b5f7d2012-01-08 23:39:40 +0200198 /* Reset all flags, except persistent ones like HCI_MGMT */
199 hdev->dev_flags &= BIT(HCI_MGMT);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200200}
201
202static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
203{
204 __u8 status = *((__u8 *) skb->data);
205 void *sent;
206
207 BT_DBG("%s status 0x%x", hdev->name, status);
208
209 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
210 if (!sent)
211 return;
212
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200213 hci_dev_lock(hdev);
214
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200215 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200216 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 if (status == 0)
219 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200220
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200221 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200222}
223
224static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
225{
226 struct hci_rp_read_local_name *rp = (void *) skb->data;
227
228 BT_DBG("%s status 0x%x", hdev->name, rp->status);
229
230 if (rp->status)
231 return;
232
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200233 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200234}
235
236static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
237{
238 __u8 status = *((__u8 *) skb->data);
239 void *sent;
240
241 BT_DBG("%s status 0x%x", hdev->name, status);
242
243 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
244 if (!sent)
245 return;
246
247 if (!status) {
248 __u8 param = *((__u8 *) sent);
249
250 if (param == AUTH_ENABLED)
251 set_bit(HCI_AUTH, &hdev->flags);
252 else
253 clear_bit(HCI_AUTH, &hdev->flags);
254 }
255
Johan Hedberg23bb5762010-12-21 23:01:27 +0200256 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200257}
258
259static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
260{
261 __u8 status = *((__u8 *) skb->data);
262 void *sent;
263
264 BT_DBG("%s status 0x%x", hdev->name, status);
265
266 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
267 if (!sent)
268 return;
269
270 if (!status) {
271 __u8 param = *((__u8 *) sent);
272
273 if (param)
274 set_bit(HCI_ENCRYPT, &hdev->flags);
275 else
276 clear_bit(HCI_ENCRYPT, &hdev->flags);
277 }
278
Johan Hedberg23bb5762010-12-21 23:01:27 +0200279 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200280}
281
282static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
283{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200284 __u8 param, status = *((__u8 *) skb->data);
285 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200286 void *sent;
287
288 BT_DBG("%s status 0x%x", hdev->name, status);
289
290 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
291 if (!sent)
292 return;
293
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200294 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200295
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200296 hci_dev_lock(hdev);
297
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200298 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200299 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200300 hdev->discov_timeout = 0;
301 goto done;
302 }
303
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200304 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
305 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200306
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200307 if (param & SCAN_INQUIRY) {
308 set_bit(HCI_ISCAN, &hdev->flags);
309 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200310 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200311 if (hdev->discov_timeout > 0) {
312 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
313 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
314 to);
315 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200316 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200317 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200318
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200319 if (param & SCAN_PAGE) {
320 set_bit(HCI_PSCAN, &hdev->flags);
321 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200322 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200324 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200325
326done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200327 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200328 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200329}
330
331static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
332{
333 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
334
335 BT_DBG("%s status 0x%x", hdev->name, rp->status);
336
337 if (rp->status)
338 return;
339
340 memcpy(hdev->dev_class, rp->dev_class, 3);
341
342 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
343 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
344}
345
346static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
347{
348 __u8 status = *((__u8 *) skb->data);
349 void *sent;
350
351 BT_DBG("%s status 0x%x", hdev->name, status);
352
Marcel Holtmannf383f272008-07-14 20:13:47 +0200353 if (status)
354 return;
355
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200356 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
357 if (!sent)
358 return;
359
Marcel Holtmannf383f272008-07-14 20:13:47 +0200360 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200361}
362
363static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
364{
365 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200367
368 BT_DBG("%s status 0x%x", hdev->name, rp->status);
369
370 if (rp->status)
371 return;
372
373 setting = __le16_to_cpu(rp->voice_setting);
374
Marcel Holtmannf383f272008-07-14 20:13:47 +0200375 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200376 return;
377
378 hdev->voice_setting = setting;
379
380 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
381
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200382 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200383 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384}
385
386static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
387{
388 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200389 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 void *sent;
391
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393
Marcel Holtmannf383f272008-07-14 20:13:47 +0200394 if (status)
395 return;
396
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200397 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
398 if (!sent)
399 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
Marcel Holtmannf383f272008-07-14 20:13:47 +0200401 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Marcel Holtmannf383f272008-07-14 20:13:47 +0200403 if (hdev->voice_setting == setting)
404 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405
Marcel Holtmannf383f272008-07-14 20:13:47 +0200406 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
409
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200410 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200411 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412}
413
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200414static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200416 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200418 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
Johan Hedberg23bb5762010-12-21 23:01:27 +0200420 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421}
422
Marcel Holtmann333140b2008-07-14 20:13:48 +0200423static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
424{
425 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
426
427 BT_DBG("%s status 0x%x", hdev->name, rp->status);
428
429 if (rp->status)
430 return;
431
432 hdev->ssp_mode = rp->mode;
433}
434
435static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
436{
437 __u8 status = *((__u8 *) skb->data);
438 void *sent;
439
440 BT_DBG("%s status 0x%x", hdev->name, status);
441
442 if (status)
443 return;
444
445 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
446 if (!sent)
447 return;
448
449 hdev->ssp_mode = *((__u8 *) sent);
450}
451
Johan Hedbergd5859e22011-01-25 01:19:58 +0200452static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
453{
454 if (hdev->features[6] & LMP_EXT_INQ)
455 return 2;
456
457 if (hdev->features[3] & LMP_RSSI_INQ)
458 return 1;
459
460 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
461 hdev->lmp_subver == 0x0757)
462 return 1;
463
464 if (hdev->manufacturer == 15) {
465 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
466 return 1;
467 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
468 return 1;
469 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
470 return 1;
471 }
472
473 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
474 hdev->lmp_subver == 0x1805)
475 return 1;
476
477 return 0;
478}
479
480static void hci_setup_inquiry_mode(struct hci_dev *hdev)
481{
482 u8 mode;
483
484 mode = hci_get_inquiry_mode(hdev);
485
486 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
487}
488
489static void hci_setup_event_mask(struct hci_dev *hdev)
490{
491 /* The second byte is 0xff instead of 0x9f (two reserved bits
492 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
493 * command otherwise */
494 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
495
Ville Tervo6de6c182011-05-27 11:16:21 +0300496 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
497 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200498 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300499 return;
500
501 events[4] |= 0x01; /* Flow Specification Complete */
502 events[4] |= 0x02; /* Inquiry Result with RSSI */
503 events[4] |= 0x04; /* Read Remote Extended Features Complete */
504 events[5] |= 0x08; /* Synchronous Connection Complete */
505 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200506
507 if (hdev->features[3] & LMP_RSSI_INQ)
508 events[4] |= 0x04; /* Inquiry Result with RSSI */
509
510 if (hdev->features[5] & LMP_SNIFF_SUBR)
511 events[5] |= 0x20; /* Sniff Subrating */
512
513 if (hdev->features[5] & LMP_PAUSE_ENC)
514 events[5] |= 0x80; /* Encryption Key Refresh Complete */
515
516 if (hdev->features[6] & LMP_EXT_INQ)
517 events[5] |= 0x40; /* Extended Inquiry Result */
518
519 if (hdev->features[6] & LMP_NO_FLUSH)
520 events[7] |= 0x01; /* Enhanced Flush Complete */
521
522 if (hdev->features[7] & LMP_LSTO)
523 events[6] |= 0x80; /* Link Supervision Timeout Changed */
524
525 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
526 events[6] |= 0x01; /* IO Capability Request */
527 events[6] |= 0x02; /* IO Capability Response */
528 events[6] |= 0x04; /* User Confirmation Request */
529 events[6] |= 0x08; /* User Passkey Request */
530 events[6] |= 0x10; /* Remote OOB Data Request */
531 events[6] |= 0x20; /* Simple Pairing Complete */
532 events[7] |= 0x04; /* User Passkey Notification */
533 events[7] |= 0x08; /* Keypress Notification */
534 events[7] |= 0x10; /* Remote Host Supported
535 * Features Notification */
536 }
537
538 if (hdev->features[4] & LMP_LE)
539 events[7] |= 0x20; /* LE Meta-Event */
540
541 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
542}
543
Andre Guedese6100a22011-06-30 19:20:54 -0300544static void hci_set_le_support(struct hci_dev *hdev)
545{
546 struct hci_cp_write_le_host_supported cp;
547
548 memset(&cp, 0, sizeof(cp));
549
550 if (enable_le) {
551 cp.le = 1;
552 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
553 }
554
555 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
556}
557
Johan Hedbergd5859e22011-01-25 01:19:58 +0200558static void hci_setup(struct hci_dev *hdev)
559{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200560 if (hdev->dev_type != HCI_BREDR)
561 return;
562
Johan Hedbergd5859e22011-01-25 01:19:58 +0200563 hci_setup_event_mask(hdev);
564
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200565 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200566 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
567
568 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
569 u8 mode = 0x01;
570 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
571 }
572
573 if (hdev->features[3] & LMP_RSSI_INQ)
574 hci_setup_inquiry_mode(hdev);
575
576 if (hdev->features[7] & LMP_INQ_TX_PWR)
577 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300578
579 if (hdev->features[7] & LMP_EXTFEATURES) {
580 struct hci_cp_read_local_ext_features cp;
581
582 cp.page = 0x01;
583 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
584 sizeof(cp), &cp);
585 }
Andre Guedese6100a22011-06-30 19:20:54 -0300586
587 if (hdev->features[4] & LMP_LE)
588 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200589}
590
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200591static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
592{
593 struct hci_rp_read_local_version *rp = (void *) skb->data;
594
595 BT_DBG("%s status 0x%x", hdev->name, rp->status);
596
597 if (rp->status)
598 return;
599
600 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200601 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200602 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200603 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200604 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200605
606 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
607 hdev->manufacturer,
608 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200609
610 if (test_bit(HCI_INIT, &hdev->flags))
611 hci_setup(hdev);
612}
613
614static void hci_setup_link_policy(struct hci_dev *hdev)
615{
616 u16 link_policy = 0;
617
618 if (hdev->features[0] & LMP_RSWITCH)
619 link_policy |= HCI_LP_RSWITCH;
620 if (hdev->features[0] & LMP_HOLD)
621 link_policy |= HCI_LP_HOLD;
622 if (hdev->features[0] & LMP_SNIFF)
623 link_policy |= HCI_LP_SNIFF;
624 if (hdev->features[1] & LMP_PARK)
625 link_policy |= HCI_LP_PARK;
626
627 link_policy = cpu_to_le16(link_policy);
628 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
629 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200630}
631
632static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
633{
634 struct hci_rp_read_local_commands *rp = (void *) skb->data;
635
636 BT_DBG("%s status 0x%x", hdev->name, rp->status);
637
638 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200639 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200640
641 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200642
643 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
644 hci_setup_link_policy(hdev);
645
646done:
647 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200648}
649
650static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
651{
652 struct hci_rp_read_local_features *rp = (void *) skb->data;
653
654 BT_DBG("%s status 0x%x", hdev->name, rp->status);
655
656 if (rp->status)
657 return;
658
659 memcpy(hdev->features, rp->features, 8);
660
661 /* Adjust default settings according to features
662 * supported by device. */
663
664 if (hdev->features[0] & LMP_3SLOT)
665 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
666
667 if (hdev->features[0] & LMP_5SLOT)
668 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
669
670 if (hdev->features[1] & LMP_HV2) {
671 hdev->pkt_type |= (HCI_HV2);
672 hdev->esco_type |= (ESCO_HV2);
673 }
674
675 if (hdev->features[1] & LMP_HV3) {
676 hdev->pkt_type |= (HCI_HV3);
677 hdev->esco_type |= (ESCO_HV3);
678 }
679
680 if (hdev->features[3] & LMP_ESCO)
681 hdev->esco_type |= (ESCO_EV3);
682
683 if (hdev->features[4] & LMP_EV4)
684 hdev->esco_type |= (ESCO_EV4);
685
686 if (hdev->features[4] & LMP_EV5)
687 hdev->esco_type |= (ESCO_EV5);
688
Marcel Holtmannefc76882009-02-06 09:13:37 +0100689 if (hdev->features[5] & LMP_EDR_ESCO_2M)
690 hdev->esco_type |= (ESCO_2EV3);
691
692 if (hdev->features[5] & LMP_EDR_ESCO_3M)
693 hdev->esco_type |= (ESCO_3EV3);
694
695 if (hdev->features[5] & LMP_EDR_3S_ESCO)
696 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
697
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200698 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
699 hdev->features[0], hdev->features[1],
700 hdev->features[2], hdev->features[3],
701 hdev->features[4], hdev->features[5],
702 hdev->features[6], hdev->features[7]);
703}
704
Andre Guedes971e3a42011-06-30 19:20:52 -0300705static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
706 struct sk_buff *skb)
707{
708 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
709
710 BT_DBG("%s status 0x%x", hdev->name, rp->status);
711
712 if (rp->status)
713 return;
714
Andre Guedesb5b32b62011-12-30 10:34:04 -0300715 switch (rp->page) {
716 case 0:
717 memcpy(hdev->features, rp->features, 8);
718 break;
719 case 1:
720 memcpy(hdev->host_features, rp->features, 8);
721 break;
722 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300723
724 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
725}
726
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200727static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
728 struct sk_buff *skb)
729{
730 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
731
732 BT_DBG("%s status 0x%x", hdev->name, rp->status);
733
734 if (rp->status)
735 return;
736
737 hdev->flow_ctl_mode = rp->mode;
738
739 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
740}
741
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200742static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
743{
744 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
745
746 BT_DBG("%s status 0x%x", hdev->name, rp->status);
747
748 if (rp->status)
749 return;
750
751 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
752 hdev->sco_mtu = rp->sco_mtu;
753 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
754 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
755
756 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
757 hdev->sco_mtu = 64;
758 hdev->sco_pkts = 8;
759 }
760
761 hdev->acl_cnt = hdev->acl_pkts;
762 hdev->sco_cnt = hdev->sco_pkts;
763
764 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
765 hdev->acl_mtu, hdev->acl_pkts,
766 hdev->sco_mtu, hdev->sco_pkts);
767}
768
769static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
770{
771 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
772
773 BT_DBG("%s status 0x%x", hdev->name, rp->status);
774
775 if (!rp->status)
776 bacpy(&hdev->bdaddr, &rp->bdaddr);
777
Johan Hedberg23bb5762010-12-21 23:01:27 +0200778 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
779}
780
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200781static void hci_cc_read_data_block_size(struct hci_dev *hdev,
782 struct sk_buff *skb)
783{
784 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
785
786 BT_DBG("%s status 0x%x", hdev->name, rp->status);
787
788 if (rp->status)
789 return;
790
791 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
792 hdev->block_len = __le16_to_cpu(rp->block_len);
793 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
794
795 hdev->block_cnt = hdev->num_blocks;
796
797 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
798 hdev->block_cnt, hdev->block_len);
799
800 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
801}
802
Johan Hedberg23bb5762010-12-21 23:01:27 +0200803static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
804{
805 __u8 status = *((__u8 *) skb->data);
806
807 BT_DBG("%s status 0x%x", hdev->name, status);
808
809 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200810}
811
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300812static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
813 struct sk_buff *skb)
814{
815 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
816
817 BT_DBG("%s status 0x%x", hdev->name, rp->status);
818
819 if (rp->status)
820 return;
821
822 hdev->amp_status = rp->amp_status;
823 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
824 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
825 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
826 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
827 hdev->amp_type = rp->amp_type;
828 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
829 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
830 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
831 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
832
833 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
834}
835
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200836static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
837 struct sk_buff *skb)
838{
839 __u8 status = *((__u8 *) skb->data);
840
841 BT_DBG("%s status 0x%x", hdev->name, status);
842
843 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
844}
845
Johan Hedbergd5859e22011-01-25 01:19:58 +0200846static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
847{
848 __u8 status = *((__u8 *) skb->data);
849
850 BT_DBG("%s status 0x%x", hdev->name, status);
851
852 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
853}
854
855static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
856 struct sk_buff *skb)
857{
858 __u8 status = *((__u8 *) skb->data);
859
860 BT_DBG("%s status 0x%x", hdev->name, status);
861
862 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
863}
864
865static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
866 struct sk_buff *skb)
867{
868 __u8 status = *((__u8 *) skb->data);
869
870 BT_DBG("%s status 0x%x", hdev->name, status);
871
872 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
873}
874
875static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
876{
877 __u8 status = *((__u8 *) skb->data);
878
879 BT_DBG("%s status 0x%x", hdev->name, status);
880
881 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
882}
883
Johan Hedberg980e1a52011-01-22 06:10:07 +0200884static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
885{
886 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
887 struct hci_cp_pin_code_reply *cp;
888 struct hci_conn *conn;
889
890 BT_DBG("%s status 0x%x", hdev->name, rp->status);
891
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200892 hci_dev_lock(hdev);
893
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200894 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200895 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200896
897 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200898 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200899
900 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
901 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200902 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200903
904 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
905 if (conn)
906 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200907
908unlock:
909 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200910}
911
912static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
913{
914 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
915
916 BT_DBG("%s status 0x%x", hdev->name, rp->status);
917
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200918 hci_dev_lock(hdev);
919
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200920 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200921 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200922 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200923
924 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200925}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200926
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300927static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
928 struct sk_buff *skb)
929{
930 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
931
932 BT_DBG("%s status 0x%x", hdev->name, rp->status);
933
934 if (rp->status)
935 return;
936
937 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
938 hdev->le_pkts = rp->le_max_pkt;
939
940 hdev->le_cnt = hdev->le_pkts;
941
942 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
943
944 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
945}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200946
Johan Hedberga5c29682011-02-19 12:05:57 -0300947static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
948{
949 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
950
951 BT_DBG("%s status 0x%x", hdev->name, rp->status);
952
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200953 hci_dev_lock(hdev);
954
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200955 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200956 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300957 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200958
959 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300960}
961
962static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
963 struct sk_buff *skb)
964{
965 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
966
967 BT_DBG("%s status 0x%x", hdev->name, rp->status);
968
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200969 hci_dev_lock(hdev);
970
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200971 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200972 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300973 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200974
975 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300976}
977
Brian Gix1143d452011-11-23 08:28:34 -0800978static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
979{
980 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
981
982 BT_DBG("%s status 0x%x", hdev->name, rp->status);
983
984 hci_dev_lock(hdev);
985
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200986 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800987 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr,
988 rp->status);
989
990 hci_dev_unlock(hdev);
991}
992
993static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
994 struct sk_buff *skb)
995{
996 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
997
998 BT_DBG("%s status 0x%x", hdev->name, rp->status);
999
1000 hci_dev_lock(hdev);
1001
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001002 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001003 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
1004 rp->status);
1005
1006 hci_dev_unlock(hdev);
1007}
1008
Szymon Jancc35938b2011-03-22 13:12:21 +01001009static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1010 struct sk_buff *skb)
1011{
1012 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1013
1014 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1015
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001016 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001017 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001018 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001019 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001020}
1021
Andre Guedes07f7fa52011-12-02 21:13:31 +09001022static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1023{
1024 __u8 status = *((__u8 *) skb->data);
1025
1026 BT_DBG("%s status 0x%x", hdev->name, status);
1027}
1028
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001029static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1030 struct sk_buff *skb)
1031{
1032 struct hci_cp_le_set_scan_enable *cp;
1033 __u8 status = *((__u8 *) skb->data);
1034
1035 BT_DBG("%s status 0x%x", hdev->name, status);
1036
1037 if (status)
1038 return;
1039
1040 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1041 if (!cp)
1042 return;
1043
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001044 switch (cp->enable) {
1045 case LE_SCANNING_ENABLED:
Andre Guedesd23264a2011-11-25 20:53:38 -03001046 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1047
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001048 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001049
1050 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001051 hci_adv_entries_clear(hdev);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001052 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001053 break;
1054
1055 case LE_SCANNING_DISABLED:
Andre Guedesd23264a2011-11-25 20:53:38 -03001056 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1057
Andre Guedesd0843292012-01-02 19:18:11 -03001058 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001059 break;
1060
1061 default:
1062 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1063 break;
Andre Guedes35815082011-05-26 16:23:53 -03001064 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001065}
1066
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001067static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1068{
1069 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1070
1071 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1072
1073 if (rp->status)
1074 return;
1075
1076 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1077}
1078
1079static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1080{
1081 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1082
1083 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1084
1085 if (rp->status)
1086 return;
1087
1088 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1089}
1090
Andre Guedesf9b49302011-06-30 19:20:53 -03001091static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1092 struct sk_buff *skb)
1093{
1094 struct hci_cp_read_local_ext_features cp;
1095 __u8 status = *((__u8 *) skb->data);
1096
1097 BT_DBG("%s status 0x%x", hdev->name, status);
1098
1099 if (status)
1100 return;
1101
1102 cp.page = 0x01;
1103 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1104}
1105
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001106static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1107{
1108 BT_DBG("%s status 0x%x", hdev->name, status);
1109
1110 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001111 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001112 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001113 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001114 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001115 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001116 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001117 return;
1118 }
1119
Andre Guedes89352e72011-11-04 14:16:53 -03001120 set_bit(HCI_INQUIRY, &hdev->flags);
1121
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001122 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001123 hci_discovery_set_state(hdev, DISCOVERY_INQUIRY);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001124 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001125}
1126
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1128{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001129 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001132 BT_DBG("%s status 0x%x", hdev->name, status);
1133
1134 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 if (!cp)
1136 return;
1137
1138 hci_dev_lock(hdev);
1139
1140 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1141
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001142 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143
1144 if (status) {
1145 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001146 if (status != 0x0c || conn->attempt > 2) {
1147 conn->state = BT_CLOSED;
1148 hci_proto_connect_cfm(conn, status);
1149 hci_conn_del(conn);
1150 } else
1151 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 }
1153 } else {
1154 if (!conn) {
1155 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1156 if (conn) {
1157 conn->out = 1;
1158 conn->link_mode |= HCI_LM_MASTER;
1159 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001160 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 }
1162 }
1163
1164 hci_dev_unlock(hdev);
1165}
1166
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001167static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001169 struct hci_cp_add_sco *cp;
1170 struct hci_conn *acl, *sco;
1171 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001173 BT_DBG("%s status 0x%x", hdev->name, status);
1174
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001175 if (!status)
1176 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001178 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1179 if (!cp)
1180 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001182 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001184 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001185
1186 hci_dev_lock(hdev);
1187
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001188 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001189 if (acl) {
1190 sco = acl->link;
1191 if (sco) {
1192 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001193
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001194 hci_proto_connect_cfm(sco, status);
1195 hci_conn_del(sco);
1196 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001197 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001198
1199 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200}
1201
Marcel Holtmannf8558552008-07-14 20:13:49 +02001202static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1203{
1204 struct hci_cp_auth_requested *cp;
1205 struct hci_conn *conn;
1206
1207 BT_DBG("%s status 0x%x", hdev->name, status);
1208
1209 if (!status)
1210 return;
1211
1212 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1213 if (!cp)
1214 return;
1215
1216 hci_dev_lock(hdev);
1217
1218 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1219 if (conn) {
1220 if (conn->state == BT_CONFIG) {
1221 hci_proto_connect_cfm(conn, status);
1222 hci_conn_put(conn);
1223 }
1224 }
1225
1226 hci_dev_unlock(hdev);
1227}
1228
1229static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1230{
1231 struct hci_cp_set_conn_encrypt *cp;
1232 struct hci_conn *conn;
1233
1234 BT_DBG("%s status 0x%x", hdev->name, status);
1235
1236 if (!status)
1237 return;
1238
1239 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1240 if (!cp)
1241 return;
1242
1243 hci_dev_lock(hdev);
1244
1245 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1246 if (conn) {
1247 if (conn->state == BT_CONFIG) {
1248 hci_proto_connect_cfm(conn, status);
1249 hci_conn_put(conn);
1250 }
1251 }
1252
1253 hci_dev_unlock(hdev);
1254}
1255
Johan Hedberg127178d2010-11-18 22:22:29 +02001256static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001257 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001258{
Johan Hedberg392599b2010-11-18 22:22:28 +02001259 if (conn->state != BT_CONFIG || !conn->out)
1260 return 0;
1261
Johan Hedberg765c2a92011-01-19 12:06:52 +05301262 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001263 return 0;
1264
1265 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001266 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedberg392599b2010-11-18 22:22:28 +02001267 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001268 conn->pending_sec_level != BT_SECURITY_HIGH &&
1269 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001270 return 0;
1271
Johan Hedberg392599b2010-11-18 22:22:28 +02001272 return 1;
1273}
1274
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001275static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1276{
1277 struct hci_cp_remote_name_req cp;
1278
1279 memset(&cp, 0, sizeof(cp));
1280
1281 bacpy(&cp.bdaddr, &e->data.bdaddr);
1282 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1283 cp.pscan_mode = e->data.pscan_mode;
1284 cp.clock_offset = e->data.clock_offset;
1285
1286 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1287}
1288
1289static void hci_resolve_next_name(struct hci_dev *hdev, bdaddr_t *bdaddr)
1290{
1291 struct discovery_state *discov = &hdev->discovery;
1292 struct inquiry_entry *e;
1293
1294 if (discov->state == DISCOVERY_STOPPING)
1295 goto discov_complete;
1296
1297 if (discov->state != DISCOVERY_RESOLVING)
1298 return;
1299
1300 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1301 if (e) {
1302 e->name_state = NAME_KNOWN;
1303 list_del(&e->list);
1304 }
1305
1306 if (list_empty(&discov->resolve))
1307 goto discov_complete;
1308
1309 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1310 if (hci_resolve_name(hdev, e) == 0) {
1311 e->name_state = NAME_PENDING;
1312 return;
1313 }
1314
1315discov_complete:
1316 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1317}
1318
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001319static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1320{
Johan Hedberg127178d2010-11-18 22:22:29 +02001321 struct hci_cp_remote_name_req *cp;
1322 struct hci_conn *conn;
1323
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001324 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001325
1326 /* If successful wait for the name req complete event before
1327 * checking for the need to do authentication */
1328 if (!status)
1329 return;
1330
1331 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1332 if (!cp)
1333 return;
1334
1335 hci_dev_lock(hdev);
1336
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001337 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001338 hci_resolve_next_name(hdev, &cp->bdaddr);
1339
Johan Hedberg127178d2010-11-18 22:22:29 +02001340 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001341 if (!conn)
1342 goto unlock;
1343
1344 if (!hci_outgoing_auth_needed(hdev, conn))
1345 goto unlock;
1346
1347 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001348 struct hci_cp_auth_requested cp;
1349 cp.handle = __cpu_to_le16(conn->handle);
1350 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1351 }
1352
Johan Hedberg79c6c702011-04-28 11:28:55 -07001353unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001354 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001355}
1356
Marcel Holtmann769be972008-07-14 20:13:49 +02001357static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1358{
1359 struct hci_cp_read_remote_features *cp;
1360 struct hci_conn *conn;
1361
1362 BT_DBG("%s status 0x%x", hdev->name, status);
1363
1364 if (!status)
1365 return;
1366
1367 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1368 if (!cp)
1369 return;
1370
1371 hci_dev_lock(hdev);
1372
1373 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1374 if (conn) {
1375 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001376 hci_proto_connect_cfm(conn, status);
1377 hci_conn_put(conn);
1378 }
1379 }
1380
1381 hci_dev_unlock(hdev);
1382}
1383
1384static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1385{
1386 struct hci_cp_read_remote_ext_features *cp;
1387 struct hci_conn *conn;
1388
1389 BT_DBG("%s status 0x%x", hdev->name, status);
1390
1391 if (!status)
1392 return;
1393
1394 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1395 if (!cp)
1396 return;
1397
1398 hci_dev_lock(hdev);
1399
1400 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1401 if (conn) {
1402 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001403 hci_proto_connect_cfm(conn, status);
1404 hci_conn_put(conn);
1405 }
1406 }
1407
1408 hci_dev_unlock(hdev);
1409}
1410
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001411static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1412{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001413 struct hci_cp_setup_sync_conn *cp;
1414 struct hci_conn *acl, *sco;
1415 __u16 handle;
1416
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001417 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001418
1419 if (!status)
1420 return;
1421
1422 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1423 if (!cp)
1424 return;
1425
1426 handle = __le16_to_cpu(cp->handle);
1427
1428 BT_DBG("%s handle %d", hdev->name, handle);
1429
1430 hci_dev_lock(hdev);
1431
1432 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001433 if (acl) {
1434 sco = acl->link;
1435 if (sco) {
1436 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001437
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001438 hci_proto_connect_cfm(sco, status);
1439 hci_conn_del(sco);
1440 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001441 }
1442
1443 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001444}
1445
1446static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1447{
1448 struct hci_cp_sniff_mode *cp;
1449 struct hci_conn *conn;
1450
1451 BT_DBG("%s status 0x%x", hdev->name, status);
1452
1453 if (!status)
1454 return;
1455
1456 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1457 if (!cp)
1458 return;
1459
1460 hci_dev_lock(hdev);
1461
1462 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001463 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001464 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1465
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001466 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1467 hci_sco_setup(conn, status);
1468 }
1469
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001470 hci_dev_unlock(hdev);
1471}
1472
1473static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1474{
1475 struct hci_cp_exit_sniff_mode *cp;
1476 struct hci_conn *conn;
1477
1478 BT_DBG("%s status 0x%x", hdev->name, status);
1479
1480 if (!status)
1481 return;
1482
1483 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1484 if (!cp)
1485 return;
1486
1487 hci_dev_lock(hdev);
1488
1489 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001490 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001491 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1492
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001493 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1494 hci_sco_setup(conn, status);
1495 }
1496
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001497 hci_dev_unlock(hdev);
1498}
1499
Ville Tervofcd89c02011-02-10 22:38:47 -03001500static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1501{
1502 struct hci_cp_le_create_conn *cp;
1503 struct hci_conn *conn;
1504
1505 BT_DBG("%s status 0x%x", hdev->name, status);
1506
1507 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1508 if (!cp)
1509 return;
1510
1511 hci_dev_lock(hdev);
1512
1513 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1514
1515 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1516 conn);
1517
1518 if (status) {
1519 if (conn && conn->state == BT_CONNECT) {
1520 conn->state = BT_CLOSED;
1521 hci_proto_connect_cfm(conn, status);
1522 hci_conn_del(conn);
1523 }
1524 } else {
1525 if (!conn) {
1526 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001527 if (conn) {
1528 conn->dst_type = cp->peer_addr_type;
Ville Tervofcd89c02011-02-10 22:38:47 -03001529 conn->out = 1;
Andre Guedes29b79882011-05-31 14:20:54 -03001530 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001531 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001532 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001533 }
1534 }
1535
1536 hci_dev_unlock(hdev);
1537}
1538
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001539static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1540{
1541 BT_DBG("%s status 0x%x", hdev->name, status);
1542}
1543
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001544static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1545{
1546 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001547 struct discovery_state *discov = &hdev->discovery;
1548 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001549
1550 BT_DBG("%s status %d", hdev->name, status);
1551
Johan Hedberg23bb5762010-12-21 23:01:27 +02001552 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001553
1554 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001555
1556 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1557 return;
1558
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001559 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001560 return;
1561
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001562 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001563
1564 if (discov->state != DISCOVERY_INQUIRY)
1565 goto unlock;
1566
1567 if (list_empty(&discov->resolve)) {
1568 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1569 goto unlock;
1570 }
1571
1572 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1573 if (e && hci_resolve_name(hdev, e) == 0) {
1574 e->name_state = NAME_PENDING;
1575 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1576 } else {
1577 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1578 }
1579
1580unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001581 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001582}
1583
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1585{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001586 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001587 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588 int num_rsp = *((__u8 *) skb->data);
1589
1590 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1591
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001592 if (!num_rsp)
1593 return;
1594
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001596
Johan Hedberge17acd42011-03-30 23:57:16 +03001597 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg31754052012-01-04 13:39:52 +02001598 bool name_known;
1599
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 bacpy(&data.bdaddr, &info->bdaddr);
1601 data.pscan_rep_mode = info->pscan_rep_mode;
1602 data.pscan_period_mode = info->pscan_period_mode;
1603 data.pscan_mode = info->pscan_mode;
1604 memcpy(data.dev_class, info->dev_class, 3);
1605 data.clock_offset = info->clock_offset;
1606 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001607 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001608
1609 name_known = hci_inquiry_cache_update(hdev, &data, false);
Johan Hedberg48264f02011-11-09 13:58:58 +02001610 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg31754052012-01-04 13:39:52 +02001611 info->dev_class, 0, !name_known, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001613
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 hci_dev_unlock(hdev);
1615}
1616
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001617static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001619 struct hci_ev_conn_complete *ev = (void *) skb->data;
1620 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001622 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001623
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001625
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001626 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001627 if (!conn) {
1628 if (ev->link_type != SCO_LINK)
1629 goto unlock;
1630
1631 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1632 if (!conn)
1633 goto unlock;
1634
1635 conn->type = SCO_LINK;
1636 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001637
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001638 if (!ev->status) {
1639 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001640
1641 if (conn->type == ACL_LINK) {
1642 conn->state = BT_CONFIG;
1643 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001644 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg48264f02011-11-09 13:58:58 +02001645 mgmt_connected(hdev, &ev->bdaddr, conn->type,
1646 conn->dst_type);
Marcel Holtmann769be972008-07-14 20:13:49 +02001647 } else
1648 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001649
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001650 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001651 hci_conn_add_sysfs(conn);
1652
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001653 if (test_bit(HCI_AUTH, &hdev->flags))
1654 conn->link_mode |= HCI_LM_AUTH;
1655
1656 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1657 conn->link_mode |= HCI_LM_ENCRYPT;
1658
1659 /* Get remote features */
1660 if (conn->type == ACL_LINK) {
1661 struct hci_cp_read_remote_features cp;
1662 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001663 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1664 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001665 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001666
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001667 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001668 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001669 struct hci_cp_change_conn_ptype cp;
1670 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001671 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1672 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1673 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001674 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001675 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001676 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001677 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001678 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001679 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001680 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001681
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001682 if (conn->type == ACL_LINK)
1683 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001684
Marcel Holtmann769be972008-07-14 20:13:49 +02001685 if (ev->status) {
1686 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001687 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001688 } else if (ev->link_type != ACL_LINK)
1689 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001690
1691unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001693
1694 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695}
1696
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1698{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001699 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 int mask = hdev->link_mode;
1701
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001702 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1703 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704
1705 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1706
Szymon Janc138d22e2011-02-17 16:44:23 +01001707 if ((mask & HCI_LM_ACCEPT) &&
1708 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001710 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712
1713 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001714
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001715 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1716 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001717 memcpy(ie->data.dev_class, ev->dev_class, 3);
1718
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1720 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001721 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1722 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001723 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724 hci_dev_unlock(hdev);
1725 return;
1726 }
1727 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001728
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 memcpy(conn->dev_class, ev->dev_class, 3);
1730 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001731
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 hci_dev_unlock(hdev);
1733
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001734 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1735 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001737 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001739 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1740 cp.role = 0x00; /* Become master */
1741 else
1742 cp.role = 0x01; /* Remain slave */
1743
1744 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1745 sizeof(cp), &cp);
1746 } else {
1747 struct hci_cp_accept_sync_conn_req cp;
1748
1749 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001750 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001751
1752 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1753 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1754 cp.max_latency = cpu_to_le16(0xffff);
1755 cp.content_format = cpu_to_le16(hdev->voice_setting);
1756 cp.retrans_effort = 0xff;
1757
1758 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1759 sizeof(cp), &cp);
1760 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 } else {
1762 /* Connection rejected */
1763 struct hci_cp_reject_conn_req cp;
1764
1765 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001766 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001767 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 }
1769}
1770
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1772{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001773 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001774 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775
1776 BT_DBG("%s status %d", hdev->name, ev->status);
1777
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 hci_dev_lock(hdev);
1779
Marcel Holtmann04837f62006-07-03 10:02:33 +02001780 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001781 if (!conn)
1782 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001783
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001784 if (ev->status == 0)
1785 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001787 if (conn->type == ACL_LINK || conn->type == LE_LINK) {
1788 if (ev->status != 0)
1789 mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
1790 else
1791 mgmt_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001792 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001793 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001794
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001795 if (ev->status == 0) {
1796 hci_proto_disconn_cfm(conn, ev->reason);
1797 hci_conn_del(conn);
1798 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001799
1800unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 hci_dev_unlock(hdev);
1802}
1803
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001804static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1805{
1806 struct hci_ev_auth_complete *ev = (void *) skb->data;
1807 struct hci_conn *conn;
1808
1809 BT_DBG("%s status %d", hdev->name, ev->status);
1810
1811 hci_dev_lock(hdev);
1812
1813 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001814 if (!conn)
1815 goto unlock;
1816
1817 if (!ev->status) {
1818 if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) &&
1819 test_bit(HCI_CONN_REAUTH_PEND, &conn->pend)) {
1820 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001821 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001822 conn->link_mode |= HCI_LM_AUTH;
1823 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001824 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001825 } else {
Johan Hedberg744cf192011-11-08 20:40:14 +02001826 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001827 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001828
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001829 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1830 clear_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001831
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001832 if (conn->state == BT_CONFIG) {
1833 if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) {
1834 struct hci_cp_set_conn_encrypt cp;
1835 cp.handle = ev->handle;
1836 cp.encrypt = 0x01;
1837 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1838 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001839 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001840 conn->state = BT_CONNECTED;
1841 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001842 hci_conn_put(conn);
1843 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001844 } else {
1845 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001846
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001847 hci_conn_hold(conn);
1848 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1849 hci_conn_put(conn);
1850 }
1851
1852 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1853 if (!ev->status) {
1854 struct hci_cp_set_conn_encrypt cp;
1855 cp.handle = ev->handle;
1856 cp.encrypt = 0x01;
1857 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1858 &cp);
1859 } else {
1860 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1861 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001862 }
1863 }
1864
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001865unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001866 hci_dev_unlock(hdev);
1867}
1868
1869static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1870{
Johan Hedberg127178d2010-11-18 22:22:29 +02001871 struct hci_ev_remote_name *ev = (void *) skb->data;
1872 struct hci_conn *conn;
1873
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001874 BT_DBG("%s", hdev->name);
1875
1876 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001877
1878 hci_dev_lock(hdev);
1879
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001880 if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001881 if (ev->status == 0)
1882 mgmt_remote_name(hdev, &ev->bdaddr, ev->name);
1883
1884 hci_resolve_next_name(hdev, &ev->bdaddr);
1885 }
Johan Hedberga88a9652011-03-30 13:18:12 +03001886
Johan Hedberg127178d2010-11-18 22:22:29 +02001887 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001888 if (!conn)
1889 goto unlock;
1890
1891 if (!hci_outgoing_auth_needed(hdev, conn))
1892 goto unlock;
1893
1894 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001895 struct hci_cp_auth_requested cp;
1896 cp.handle = __cpu_to_le16(conn->handle);
1897 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1898 }
1899
Johan Hedberg79c6c702011-04-28 11:28:55 -07001900unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001901 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001902}
1903
1904static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1905{
1906 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1907 struct hci_conn *conn;
1908
1909 BT_DBG("%s status %d", hdev->name, ev->status);
1910
1911 hci_dev_lock(hdev);
1912
1913 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1914 if (conn) {
1915 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001916 if (ev->encrypt) {
1917 /* Encryption implies authentication */
1918 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001919 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001920 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001921 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001922 conn->link_mode &= ~HCI_LM_ENCRYPT;
1923 }
1924
1925 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1926
Marcel Holtmannf8558552008-07-14 20:13:49 +02001927 if (conn->state == BT_CONFIG) {
1928 if (!ev->status)
1929 conn->state = BT_CONNECTED;
1930
1931 hci_proto_connect_cfm(conn, ev->status);
1932 hci_conn_put(conn);
1933 } else
1934 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001935 }
1936
1937 hci_dev_unlock(hdev);
1938}
1939
1940static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1941{
1942 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1943 struct hci_conn *conn;
1944
1945 BT_DBG("%s status %d", hdev->name, ev->status);
1946
1947 hci_dev_lock(hdev);
1948
1949 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1950 if (conn) {
1951 if (!ev->status)
1952 conn->link_mode |= HCI_LM_SECURE;
1953
1954 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1955
1956 hci_key_change_cfm(conn, ev->status);
1957 }
1958
1959 hci_dev_unlock(hdev);
1960}
1961
1962static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1963{
1964 struct hci_ev_remote_features *ev = (void *) skb->data;
1965 struct hci_conn *conn;
1966
1967 BT_DBG("%s status %d", hdev->name, ev->status);
1968
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001969 hci_dev_lock(hdev);
1970
1971 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001972 if (!conn)
1973 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001974
Johan Hedbergccd556f2010-11-10 17:11:51 +02001975 if (!ev->status)
1976 memcpy(conn->features, ev->features, 8);
1977
1978 if (conn->state != BT_CONFIG)
1979 goto unlock;
1980
1981 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1982 struct hci_cp_read_remote_ext_features cp;
1983 cp.handle = ev->handle;
1984 cp.page = 0x01;
1985 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001986 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001987 goto unlock;
1988 }
1989
Johan Hedberg127178d2010-11-18 22:22:29 +02001990 if (!ev->status) {
1991 struct hci_cp_remote_name_req cp;
1992 memset(&cp, 0, sizeof(cp));
1993 bacpy(&cp.bdaddr, &conn->dst);
1994 cp.pscan_rep_mode = 0x02;
1995 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1996 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001997
Johan Hedberg127178d2010-11-18 22:22:29 +02001998 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001999 conn->state = BT_CONNECTED;
2000 hci_proto_connect_cfm(conn, ev->status);
2001 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002002 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002003
Johan Hedbergccd556f2010-11-10 17:11:51 +02002004unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002005 hci_dev_unlock(hdev);
2006}
2007
2008static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2009{
2010 BT_DBG("%s", hdev->name);
2011}
2012
2013static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2014{
2015 BT_DBG("%s", hdev->name);
2016}
2017
2018static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2019{
2020 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2021 __u16 opcode;
2022
2023 skb_pull(skb, sizeof(*ev));
2024
2025 opcode = __le16_to_cpu(ev->opcode);
2026
2027 switch (opcode) {
2028 case HCI_OP_INQUIRY_CANCEL:
2029 hci_cc_inquiry_cancel(hdev, skb);
2030 break;
2031
2032 case HCI_OP_EXIT_PERIODIC_INQ:
2033 hci_cc_exit_periodic_inq(hdev, skb);
2034 break;
2035
2036 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2037 hci_cc_remote_name_req_cancel(hdev, skb);
2038 break;
2039
2040 case HCI_OP_ROLE_DISCOVERY:
2041 hci_cc_role_discovery(hdev, skb);
2042 break;
2043
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002044 case HCI_OP_READ_LINK_POLICY:
2045 hci_cc_read_link_policy(hdev, skb);
2046 break;
2047
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002048 case HCI_OP_WRITE_LINK_POLICY:
2049 hci_cc_write_link_policy(hdev, skb);
2050 break;
2051
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002052 case HCI_OP_READ_DEF_LINK_POLICY:
2053 hci_cc_read_def_link_policy(hdev, skb);
2054 break;
2055
2056 case HCI_OP_WRITE_DEF_LINK_POLICY:
2057 hci_cc_write_def_link_policy(hdev, skb);
2058 break;
2059
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002060 case HCI_OP_RESET:
2061 hci_cc_reset(hdev, skb);
2062 break;
2063
2064 case HCI_OP_WRITE_LOCAL_NAME:
2065 hci_cc_write_local_name(hdev, skb);
2066 break;
2067
2068 case HCI_OP_READ_LOCAL_NAME:
2069 hci_cc_read_local_name(hdev, skb);
2070 break;
2071
2072 case HCI_OP_WRITE_AUTH_ENABLE:
2073 hci_cc_write_auth_enable(hdev, skb);
2074 break;
2075
2076 case HCI_OP_WRITE_ENCRYPT_MODE:
2077 hci_cc_write_encrypt_mode(hdev, skb);
2078 break;
2079
2080 case HCI_OP_WRITE_SCAN_ENABLE:
2081 hci_cc_write_scan_enable(hdev, skb);
2082 break;
2083
2084 case HCI_OP_READ_CLASS_OF_DEV:
2085 hci_cc_read_class_of_dev(hdev, skb);
2086 break;
2087
2088 case HCI_OP_WRITE_CLASS_OF_DEV:
2089 hci_cc_write_class_of_dev(hdev, skb);
2090 break;
2091
2092 case HCI_OP_READ_VOICE_SETTING:
2093 hci_cc_read_voice_setting(hdev, skb);
2094 break;
2095
2096 case HCI_OP_WRITE_VOICE_SETTING:
2097 hci_cc_write_voice_setting(hdev, skb);
2098 break;
2099
2100 case HCI_OP_HOST_BUFFER_SIZE:
2101 hci_cc_host_buffer_size(hdev, skb);
2102 break;
2103
Marcel Holtmann333140b2008-07-14 20:13:48 +02002104 case HCI_OP_READ_SSP_MODE:
2105 hci_cc_read_ssp_mode(hdev, skb);
2106 break;
2107
2108 case HCI_OP_WRITE_SSP_MODE:
2109 hci_cc_write_ssp_mode(hdev, skb);
2110 break;
2111
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002112 case HCI_OP_READ_LOCAL_VERSION:
2113 hci_cc_read_local_version(hdev, skb);
2114 break;
2115
2116 case HCI_OP_READ_LOCAL_COMMANDS:
2117 hci_cc_read_local_commands(hdev, skb);
2118 break;
2119
2120 case HCI_OP_READ_LOCAL_FEATURES:
2121 hci_cc_read_local_features(hdev, skb);
2122 break;
2123
Andre Guedes971e3a42011-06-30 19:20:52 -03002124 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2125 hci_cc_read_local_ext_features(hdev, skb);
2126 break;
2127
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002128 case HCI_OP_READ_BUFFER_SIZE:
2129 hci_cc_read_buffer_size(hdev, skb);
2130 break;
2131
2132 case HCI_OP_READ_BD_ADDR:
2133 hci_cc_read_bd_addr(hdev, skb);
2134 break;
2135
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002136 case HCI_OP_READ_DATA_BLOCK_SIZE:
2137 hci_cc_read_data_block_size(hdev, skb);
2138 break;
2139
Johan Hedberg23bb5762010-12-21 23:01:27 +02002140 case HCI_OP_WRITE_CA_TIMEOUT:
2141 hci_cc_write_ca_timeout(hdev, skb);
2142 break;
2143
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002144 case HCI_OP_READ_FLOW_CONTROL_MODE:
2145 hci_cc_read_flow_control_mode(hdev, skb);
2146 break;
2147
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002148 case HCI_OP_READ_LOCAL_AMP_INFO:
2149 hci_cc_read_local_amp_info(hdev, skb);
2150 break;
2151
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002152 case HCI_OP_DELETE_STORED_LINK_KEY:
2153 hci_cc_delete_stored_link_key(hdev, skb);
2154 break;
2155
Johan Hedbergd5859e22011-01-25 01:19:58 +02002156 case HCI_OP_SET_EVENT_MASK:
2157 hci_cc_set_event_mask(hdev, skb);
2158 break;
2159
2160 case HCI_OP_WRITE_INQUIRY_MODE:
2161 hci_cc_write_inquiry_mode(hdev, skb);
2162 break;
2163
2164 case HCI_OP_READ_INQ_RSP_TX_POWER:
2165 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2166 break;
2167
2168 case HCI_OP_SET_EVENT_FLT:
2169 hci_cc_set_event_flt(hdev, skb);
2170 break;
2171
Johan Hedberg980e1a52011-01-22 06:10:07 +02002172 case HCI_OP_PIN_CODE_REPLY:
2173 hci_cc_pin_code_reply(hdev, skb);
2174 break;
2175
2176 case HCI_OP_PIN_CODE_NEG_REPLY:
2177 hci_cc_pin_code_neg_reply(hdev, skb);
2178 break;
2179
Szymon Jancc35938b2011-03-22 13:12:21 +01002180 case HCI_OP_READ_LOCAL_OOB_DATA:
2181 hci_cc_read_local_oob_data_reply(hdev, skb);
2182 break;
2183
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002184 case HCI_OP_LE_READ_BUFFER_SIZE:
2185 hci_cc_le_read_buffer_size(hdev, skb);
2186 break;
2187
Johan Hedberga5c29682011-02-19 12:05:57 -03002188 case HCI_OP_USER_CONFIRM_REPLY:
2189 hci_cc_user_confirm_reply(hdev, skb);
2190 break;
2191
2192 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2193 hci_cc_user_confirm_neg_reply(hdev, skb);
2194 break;
2195
Brian Gix1143d452011-11-23 08:28:34 -08002196 case HCI_OP_USER_PASSKEY_REPLY:
2197 hci_cc_user_passkey_reply(hdev, skb);
2198 break;
2199
2200 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2201 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002202
2203 case HCI_OP_LE_SET_SCAN_PARAM:
2204 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002205 break;
2206
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002207 case HCI_OP_LE_SET_SCAN_ENABLE:
2208 hci_cc_le_set_scan_enable(hdev, skb);
2209 break;
2210
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002211 case HCI_OP_LE_LTK_REPLY:
2212 hci_cc_le_ltk_reply(hdev, skb);
2213 break;
2214
2215 case HCI_OP_LE_LTK_NEG_REPLY:
2216 hci_cc_le_ltk_neg_reply(hdev, skb);
2217 break;
2218
Andre Guedesf9b49302011-06-30 19:20:53 -03002219 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2220 hci_cc_write_le_host_supported(hdev, skb);
2221 break;
2222
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002223 default:
2224 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2225 break;
2226 }
2227
Ville Tervo6bd32322011-02-16 16:32:41 +02002228 if (ev->opcode != HCI_OP_NOP)
2229 del_timer(&hdev->cmd_timer);
2230
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002231 if (ev->ncmd) {
2232 atomic_set(&hdev->cmd_cnt, 1);
2233 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002234 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002235 }
2236}
2237
2238static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2239{
2240 struct hci_ev_cmd_status *ev = (void *) skb->data;
2241 __u16 opcode;
2242
2243 skb_pull(skb, sizeof(*ev));
2244
2245 opcode = __le16_to_cpu(ev->opcode);
2246
2247 switch (opcode) {
2248 case HCI_OP_INQUIRY:
2249 hci_cs_inquiry(hdev, ev->status);
2250 break;
2251
2252 case HCI_OP_CREATE_CONN:
2253 hci_cs_create_conn(hdev, ev->status);
2254 break;
2255
2256 case HCI_OP_ADD_SCO:
2257 hci_cs_add_sco(hdev, ev->status);
2258 break;
2259
Marcel Holtmannf8558552008-07-14 20:13:49 +02002260 case HCI_OP_AUTH_REQUESTED:
2261 hci_cs_auth_requested(hdev, ev->status);
2262 break;
2263
2264 case HCI_OP_SET_CONN_ENCRYPT:
2265 hci_cs_set_conn_encrypt(hdev, ev->status);
2266 break;
2267
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002268 case HCI_OP_REMOTE_NAME_REQ:
2269 hci_cs_remote_name_req(hdev, ev->status);
2270 break;
2271
Marcel Holtmann769be972008-07-14 20:13:49 +02002272 case HCI_OP_READ_REMOTE_FEATURES:
2273 hci_cs_read_remote_features(hdev, ev->status);
2274 break;
2275
2276 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2277 hci_cs_read_remote_ext_features(hdev, ev->status);
2278 break;
2279
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002280 case HCI_OP_SETUP_SYNC_CONN:
2281 hci_cs_setup_sync_conn(hdev, ev->status);
2282 break;
2283
2284 case HCI_OP_SNIFF_MODE:
2285 hci_cs_sniff_mode(hdev, ev->status);
2286 break;
2287
2288 case HCI_OP_EXIT_SNIFF_MODE:
2289 hci_cs_exit_sniff_mode(hdev, ev->status);
2290 break;
2291
Johan Hedberg8962ee72011-01-20 12:40:27 +02002292 case HCI_OP_DISCONNECT:
2293 if (ev->status != 0)
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002294 mgmt_disconnect_failed(hdev, NULL, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002295 break;
2296
Ville Tervofcd89c02011-02-10 22:38:47 -03002297 case HCI_OP_LE_CREATE_CONN:
2298 hci_cs_le_create_conn(hdev, ev->status);
2299 break;
2300
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002301 case HCI_OP_LE_START_ENC:
2302 hci_cs_le_start_enc(hdev, ev->status);
2303 break;
2304
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002305 default:
2306 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2307 break;
2308 }
2309
Ville Tervo6bd32322011-02-16 16:32:41 +02002310 if (ev->opcode != HCI_OP_NOP)
2311 del_timer(&hdev->cmd_timer);
2312
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002313 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002314 atomic_set(&hdev->cmd_cnt, 1);
2315 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002316 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002317 }
2318}
2319
2320static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2321{
2322 struct hci_ev_role_change *ev = (void *) skb->data;
2323 struct hci_conn *conn;
2324
2325 BT_DBG("%s status %d", hdev->name, ev->status);
2326
2327 hci_dev_lock(hdev);
2328
2329 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2330 if (conn) {
2331 if (!ev->status) {
2332 if (ev->role)
2333 conn->link_mode &= ~HCI_LM_MASTER;
2334 else
2335 conn->link_mode |= HCI_LM_MASTER;
2336 }
2337
2338 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
2339
2340 hci_role_switch_cfm(conn, ev->status, ev->role);
2341 }
2342
2343 hci_dev_unlock(hdev);
2344}
2345
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2347{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002348 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349 int i;
2350
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002351 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2352 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2353 return;
2354 }
2355
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002356 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2357 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002358 BT_DBG("%s bad parameters", hdev->name);
2359 return;
2360 }
2361
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002362 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2363
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002364 for (i = 0; i < ev->num_hndl; i++) {
2365 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002366 struct hci_conn *conn;
2367 __u16 handle, count;
2368
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002369 handle = __le16_to_cpu(info->handle);
2370 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002371
2372 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002373 if (!conn)
2374 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002376 conn->sent -= count;
2377
2378 switch (conn->type) {
2379 case ACL_LINK:
2380 hdev->acl_cnt += count;
2381 if (hdev->acl_cnt > hdev->acl_pkts)
2382 hdev->acl_cnt = hdev->acl_pkts;
2383 break;
2384
2385 case LE_LINK:
2386 if (hdev->le_pkts) {
2387 hdev->le_cnt += count;
2388 if (hdev->le_cnt > hdev->le_pkts)
2389 hdev->le_cnt = hdev->le_pkts;
2390 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002391 hdev->acl_cnt += count;
2392 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002393 hdev->acl_cnt = hdev->acl_pkts;
2394 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002395 break;
2396
2397 case SCO_LINK:
2398 hdev->sco_cnt += count;
2399 if (hdev->sco_cnt > hdev->sco_pkts)
2400 hdev->sco_cnt = hdev->sco_pkts;
2401 break;
2402
2403 default:
2404 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2405 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406 }
2407 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002408
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002409 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410}
2411
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002412static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2413 struct sk_buff *skb)
2414{
2415 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2416 int i;
2417
2418 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2419 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2420 return;
2421 }
2422
2423 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2424 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2425 BT_DBG("%s bad parameters", hdev->name);
2426 return;
2427 }
2428
2429 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2430 ev->num_hndl);
2431
2432 for (i = 0; i < ev->num_hndl; i++) {
2433 struct hci_comp_blocks_info *info = &ev->handles[i];
2434 struct hci_conn *conn;
2435 __u16 handle, block_count;
2436
2437 handle = __le16_to_cpu(info->handle);
2438 block_count = __le16_to_cpu(info->blocks);
2439
2440 conn = hci_conn_hash_lookup_handle(hdev, handle);
2441 if (!conn)
2442 continue;
2443
2444 conn->sent -= block_count;
2445
2446 switch (conn->type) {
2447 case ACL_LINK:
2448 hdev->block_cnt += block_count;
2449 if (hdev->block_cnt > hdev->num_blocks)
2450 hdev->block_cnt = hdev->num_blocks;
2451 break;
2452
2453 default:
2454 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2455 break;
2456 }
2457 }
2458
2459 queue_work(hdev->workqueue, &hdev->tx_work);
2460}
2461
Marcel Holtmann04837f62006-07-03 10:02:33 +02002462static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002463{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002464 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002465 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002466
2467 BT_DBG("%s status %d", hdev->name, ev->status);
2468
2469 hci_dev_lock(hdev);
2470
Marcel Holtmann04837f62006-07-03 10:02:33 +02002471 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2472 if (conn) {
2473 conn->mode = ev->mode;
2474 conn->interval = __le16_to_cpu(ev->interval);
2475
2476 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
2477 if (conn->mode == HCI_CM_ACTIVE)
2478 conn->power_save = 1;
2479 else
2480 conn->power_save = 0;
2481 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002482
2483 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
2484 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002485 }
2486
2487 hci_dev_unlock(hdev);
2488}
2489
Linus Torvalds1da177e2005-04-16 15:20:36 -07002490static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2491{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002492 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2493 struct hci_conn *conn;
2494
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002495 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002496
2497 hci_dev_lock(hdev);
2498
2499 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002500 if (!conn)
2501 goto unlock;
2502
2503 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002504 hci_conn_hold(conn);
2505 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2506 hci_conn_put(conn);
2507 }
2508
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002509 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002510 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2511 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002512 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002513 u8 secure;
2514
2515 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2516 secure = 1;
2517 else
2518 secure = 0;
2519
Johan Hedberg744cf192011-11-08 20:40:14 +02002520 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002521 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002522
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002523unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002524 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525}
2526
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2528{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002529 struct hci_ev_link_key_req *ev = (void *) skb->data;
2530 struct hci_cp_link_key_reply cp;
2531 struct hci_conn *conn;
2532 struct link_key *key;
2533
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002534 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002535
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002536 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002537 return;
2538
2539 hci_dev_lock(hdev);
2540
2541 key = hci_find_link_key(hdev, &ev->bdaddr);
2542 if (!key) {
2543 BT_DBG("%s link key not found for %s", hdev->name,
2544 batostr(&ev->bdaddr));
2545 goto not_found;
2546 }
2547
2548 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2549 batostr(&ev->bdaddr));
2550
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002551 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002552 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002553 BT_DBG("%s ignoring debug key", hdev->name);
2554 goto not_found;
2555 }
2556
2557 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002558 if (conn) {
2559 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2560 conn->auth_type != 0xff &&
2561 (conn->auth_type & 0x01)) {
2562 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2563 goto not_found;
2564 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002565
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002566 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2567 conn->pending_sec_level == BT_SECURITY_HIGH) {
2568 BT_DBG("%s ignoring key unauthenticated for high \
2569 security", hdev->name);
2570 goto not_found;
2571 }
2572
2573 conn->key_type = key->type;
2574 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002575 }
2576
2577 bacpy(&cp.bdaddr, &ev->bdaddr);
2578 memcpy(cp.link_key, key->val, 16);
2579
2580 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2581
2582 hci_dev_unlock(hdev);
2583
2584 return;
2585
2586not_found:
2587 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2588 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589}
2590
Linus Torvalds1da177e2005-04-16 15:20:36 -07002591static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2592{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002593 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2594 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002595 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002596
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002597 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002598
2599 hci_dev_lock(hdev);
2600
2601 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2602 if (conn) {
2603 hci_conn_hold(conn);
2604 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002605 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002606
2607 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2608 conn->key_type = ev->key_type;
2609
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002610 hci_conn_put(conn);
2611 }
2612
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002613 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002614 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002615 ev->key_type, pin_len);
2616
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002617 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002618}
2619
Marcel Holtmann04837f62006-07-03 10:02:33 +02002620static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2621{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002622 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002623 struct hci_conn *conn;
2624
2625 BT_DBG("%s status %d", hdev->name, ev->status);
2626
2627 hci_dev_lock(hdev);
2628
2629 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630 if (conn && !ev->status) {
2631 struct inquiry_entry *ie;
2632
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002633 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2634 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002635 ie->data.clock_offset = ev->clock_offset;
2636 ie->timestamp = jiffies;
2637 }
2638 }
2639
2640 hci_dev_unlock(hdev);
2641}
2642
Marcel Holtmanna8746412008-07-14 20:13:46 +02002643static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2644{
2645 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2646 struct hci_conn *conn;
2647
2648 BT_DBG("%s status %d", hdev->name, ev->status);
2649
2650 hci_dev_lock(hdev);
2651
2652 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2653 if (conn && !ev->status)
2654 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2655
2656 hci_dev_unlock(hdev);
2657}
2658
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002659static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2660{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002661 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002662 struct inquiry_entry *ie;
2663
2664 BT_DBG("%s", hdev->name);
2665
2666 hci_dev_lock(hdev);
2667
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002668 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2669 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002670 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2671 ie->timestamp = jiffies;
2672 }
2673
2674 hci_dev_unlock(hdev);
2675}
2676
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002677static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2678{
2679 struct inquiry_data data;
2680 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg31754052012-01-04 13:39:52 +02002681 bool name_known;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002682
2683 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2684
2685 if (!num_rsp)
2686 return;
2687
2688 hci_dev_lock(hdev);
2689
2690 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002691 struct inquiry_info_with_rssi_and_pscan_mode *info;
2692 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002693
Johan Hedberge17acd42011-03-30 23:57:16 +03002694 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002695 bacpy(&data.bdaddr, &info->bdaddr);
2696 data.pscan_rep_mode = info->pscan_rep_mode;
2697 data.pscan_period_mode = info->pscan_period_mode;
2698 data.pscan_mode = info->pscan_mode;
2699 memcpy(data.dev_class, info->dev_class, 3);
2700 data.clock_offset = info->clock_offset;
2701 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002702 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002703
2704 name_known = hci_inquiry_cache_update(hdev, &data,
2705 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002706 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002707 info->dev_class, info->rssi,
Johan Hedberg31754052012-01-04 13:39:52 +02002708 !name_known, NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002709 }
2710 } else {
2711 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2712
Johan Hedberge17acd42011-03-30 23:57:16 +03002713 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002714 bacpy(&data.bdaddr, &info->bdaddr);
2715 data.pscan_rep_mode = info->pscan_rep_mode;
2716 data.pscan_period_mode = info->pscan_period_mode;
2717 data.pscan_mode = 0x00;
2718 memcpy(data.dev_class, info->dev_class, 3);
2719 data.clock_offset = info->clock_offset;
2720 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002721 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002722 name_known = hci_inquiry_cache_update(hdev, &data,
2723 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002724 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002725 info->dev_class, info->rssi,
Johan Hedberg31754052012-01-04 13:39:52 +02002726 !name_known, NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002727 }
2728 }
2729
2730 hci_dev_unlock(hdev);
2731}
2732
2733static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2734{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002735 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2736 struct hci_conn *conn;
2737
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002738 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002739
Marcel Holtmann41a96212008-07-14 20:13:48 +02002740 hci_dev_lock(hdev);
2741
2742 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002743 if (!conn)
2744 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002745
Johan Hedbergccd556f2010-11-10 17:11:51 +02002746 if (!ev->status && ev->page == 0x01) {
2747 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002748
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002749 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2750 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002751 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002752
Johan Hedbergccd556f2010-11-10 17:11:51 +02002753 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002754 }
2755
Johan Hedbergccd556f2010-11-10 17:11:51 +02002756 if (conn->state != BT_CONFIG)
2757 goto unlock;
2758
Johan Hedberg127178d2010-11-18 22:22:29 +02002759 if (!ev->status) {
2760 struct hci_cp_remote_name_req cp;
2761 memset(&cp, 0, sizeof(cp));
2762 bacpy(&cp.bdaddr, &conn->dst);
2763 cp.pscan_rep_mode = 0x02;
2764 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2765 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002766
Johan Hedberg127178d2010-11-18 22:22:29 +02002767 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002768 conn->state = BT_CONNECTED;
2769 hci_proto_connect_cfm(conn, ev->status);
2770 hci_conn_put(conn);
2771 }
2772
2773unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002774 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002775}
2776
2777static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2778{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002779 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2780 struct hci_conn *conn;
2781
2782 BT_DBG("%s status %d", hdev->name, ev->status);
2783
2784 hci_dev_lock(hdev);
2785
2786 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002787 if (!conn) {
2788 if (ev->link_type == ESCO_LINK)
2789 goto unlock;
2790
2791 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2792 if (!conn)
2793 goto unlock;
2794
2795 conn->type = SCO_LINK;
2796 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002797
Marcel Holtmann732547f2009-04-19 19:14:14 +02002798 switch (ev->status) {
2799 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002800 conn->handle = __le16_to_cpu(ev->handle);
2801 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002802
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002803 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002804 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002805 break;
2806
Stephen Coe705e5712010-02-16 11:29:44 -05002807 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002808 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002809 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002810 case 0x1f: /* Unspecified error */
2811 if (conn->out && conn->attempt < 2) {
2812 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2813 (hdev->esco_type & EDR_ESCO_MASK);
2814 hci_setup_sync(conn, conn->link->handle);
2815 goto unlock;
2816 }
2817 /* fall through */
2818
2819 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002820 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002821 break;
2822 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002823
2824 hci_proto_connect_cfm(conn, ev->status);
2825 if (ev->status)
2826 hci_conn_del(conn);
2827
2828unlock:
2829 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002830}
2831
2832static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2833{
2834 BT_DBG("%s", hdev->name);
2835}
2836
Marcel Holtmann04837f62006-07-03 10:02:33 +02002837static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2838{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002839 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002840
2841 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002842}
2843
Johan Hedberg561aafb2012-01-04 13:31:59 +02002844static inline bool eir_has_complete_name(u8 *data, size_t data_len)
2845{
2846 u8 field_len;
2847 size_t parsed;
2848
2849 for (parsed = 0; parsed < data_len - 1; parsed += field_len) {
2850 field_len = data[0];
2851
2852 if (field_len == 0)
2853 break;
2854
2855 parsed += field_len + 1;
2856
2857 if (parsed > data_len)
2858 break;
2859
2860 if (data[1] == EIR_NAME_COMPLETE)
2861 return true;
2862
2863 data += field_len + 1;
2864 }
2865
2866 return false;
2867}
2868
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002869static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2870{
2871 struct inquiry_data data;
2872 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2873 int num_rsp = *((__u8 *) skb->data);
2874
2875 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2876
2877 if (!num_rsp)
2878 return;
2879
2880 hci_dev_lock(hdev);
2881
Johan Hedberge17acd42011-03-30 23:57:16 +03002882 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg561aafb2012-01-04 13:31:59 +02002883 bool name_known;
2884
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002885 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002886 data.pscan_rep_mode = info->pscan_rep_mode;
2887 data.pscan_period_mode = info->pscan_period_mode;
2888 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002889 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002890 data.clock_offset = info->clock_offset;
2891 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002892 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002893
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002894 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg561aafb2012-01-04 13:31:59 +02002895 name_known = eir_has_complete_name(info->data,
2896 sizeof(info->data));
2897 else
2898 name_known = true;
2899
Johan Hedberg31754052012-01-04 13:39:52 +02002900 name_known = hci_inquiry_cache_update(hdev, &data, name_known);
Johan Hedberg48264f02011-11-09 13:58:58 +02002901 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002902 info->dev_class, info->rssi,
2903 !name_known, info->data);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002904 }
2905
2906 hci_dev_unlock(hdev);
2907}
2908
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002909static inline u8 hci_get_auth_req(struct hci_conn *conn)
2910{
2911 /* If remote requests dedicated bonding follow that lead */
2912 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2913 /* If both remote and local IO capabilities allow MITM
2914 * protection then require it, otherwise don't */
2915 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2916 return 0x02;
2917 else
2918 return 0x03;
2919 }
2920
2921 /* If remote requests no-bonding follow that lead */
2922 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002923 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002924
2925 return conn->auth_type;
2926}
2927
Marcel Holtmann04936842008-07-14 20:13:48 +02002928static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2929{
2930 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2931 struct hci_conn *conn;
2932
2933 BT_DBG("%s", hdev->name);
2934
2935 hci_dev_lock(hdev);
2936
2937 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002938 if (!conn)
2939 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002940
Johan Hedberg03b555e2011-01-04 15:40:05 +02002941 hci_conn_hold(conn);
2942
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002943 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002944 goto unlock;
2945
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002946 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02002947 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002948 struct hci_cp_io_capability_reply cp;
2949
2950 bacpy(&cp.bdaddr, &ev->bdaddr);
2951 cp.capability = conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07002952 conn->auth_type = hci_get_auth_req(conn);
2953 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002954
Szymon Jancce85ee12011-03-22 13:12:23 +01002955 if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
2956 hci_find_remote_oob_data(hdev, &conn->dst))
2957 cp.oob_data = 0x01;
2958 else
2959 cp.oob_data = 0x00;
2960
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002961 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2962 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002963 } else {
2964 struct hci_cp_io_capability_neg_reply cp;
2965
2966 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002967 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02002968
2969 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2970 sizeof(cp), &cp);
2971 }
2972
2973unlock:
2974 hci_dev_unlock(hdev);
2975}
2976
2977static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2978{
2979 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2980 struct hci_conn *conn;
2981
2982 BT_DBG("%s", hdev->name);
2983
2984 hci_dev_lock(hdev);
2985
2986 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2987 if (!conn)
2988 goto unlock;
2989
Johan Hedberg03b555e2011-01-04 15:40:05 +02002990 conn->remote_cap = ev->capability;
2991 conn->remote_oob = ev->oob_data;
2992 conn->remote_auth = ev->authentication;
2993
2994unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002995 hci_dev_unlock(hdev);
2996}
2997
Johan Hedberga5c29682011-02-19 12:05:57 -03002998static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2999 struct sk_buff *skb)
3000{
3001 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003002 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003003 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003004
3005 BT_DBG("%s", hdev->name);
3006
3007 hci_dev_lock(hdev);
3008
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003009 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003010 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003011
Johan Hedberg7a828902011-04-28 11:28:53 -07003012 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3013 if (!conn)
3014 goto unlock;
3015
3016 loc_mitm = (conn->auth_type & 0x01);
3017 rem_mitm = (conn->remote_auth & 0x01);
3018
3019 /* If we require MITM but the remote device can't provide that
3020 * (it has NoInputNoOutput) then reject the confirmation
3021 * request. The only exception is when we're dedicated bonding
3022 * initiators (connect_cfm_cb set) since then we always have the MITM
3023 * bit set. */
3024 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3025 BT_DBG("Rejecting request: remote device can't provide MITM");
3026 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3027 sizeof(ev->bdaddr), &ev->bdaddr);
3028 goto unlock;
3029 }
3030
3031 /* If no side requires MITM protection; auto-accept */
3032 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3033 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003034
3035 /* If we're not the initiators request authorization to
3036 * proceed from user space (mgmt_user_confirm with
3037 * confirm_hint set to 1). */
3038 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
3039 BT_DBG("Confirming auto-accept as acceptor");
3040 confirm_hint = 1;
3041 goto confirm;
3042 }
3043
Johan Hedberg9f616562011-04-28 11:28:54 -07003044 BT_DBG("Auto-accept of user confirmation with %ums delay",
3045 hdev->auto_accept_delay);
3046
3047 if (hdev->auto_accept_delay > 0) {
3048 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3049 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3050 goto unlock;
3051 }
3052
Johan Hedberg7a828902011-04-28 11:28:53 -07003053 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3054 sizeof(ev->bdaddr), &ev->bdaddr);
3055 goto unlock;
3056 }
3057
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003058confirm:
Johan Hedberg744cf192011-11-08 20:40:14 +02003059 mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003060 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003061
3062unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003063 hci_dev_unlock(hdev);
3064}
3065
Brian Gix1143d452011-11-23 08:28:34 -08003066static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3067 struct sk_buff *skb)
3068{
3069 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3070
3071 BT_DBG("%s", hdev->name);
3072
3073 hci_dev_lock(hdev);
3074
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003075 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08003076 mgmt_user_passkey_request(hdev, &ev->bdaddr);
3077
3078 hci_dev_unlock(hdev);
3079}
3080
Marcel Holtmann04936842008-07-14 20:13:48 +02003081static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3082{
3083 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3084 struct hci_conn *conn;
3085
3086 BT_DBG("%s", hdev->name);
3087
3088 hci_dev_lock(hdev);
3089
3090 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003091 if (!conn)
3092 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003093
Johan Hedberg2a611692011-02-19 12:06:00 -03003094 /* To avoid duplicate auth_failed events to user space we check
3095 * the HCI_CONN_AUTH_PEND flag which will be set if we
3096 * initiated the authentication. A traditional auth_complete
3097 * event gets always produced as initiator and is also mapped to
3098 * the mgmt_auth_failed event */
3099 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
Johan Hedberg744cf192011-11-08 20:40:14 +02003100 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003101
3102 hci_conn_put(conn);
3103
3104unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003105 hci_dev_unlock(hdev);
3106}
3107
Marcel Holtmann41a96212008-07-14 20:13:48 +02003108static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3109{
3110 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3111 struct inquiry_entry *ie;
3112
3113 BT_DBG("%s", hdev->name);
3114
3115 hci_dev_lock(hdev);
3116
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003117 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3118 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003119 ie->data.ssp_mode = (ev->features[0] & 0x01);
3120
3121 hci_dev_unlock(hdev);
3122}
3123
Szymon Janc2763eda2011-03-22 13:12:22 +01003124static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3125 struct sk_buff *skb)
3126{
3127 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3128 struct oob_data *data;
3129
3130 BT_DBG("%s", hdev->name);
3131
3132 hci_dev_lock(hdev);
3133
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003134 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003135 goto unlock;
3136
Szymon Janc2763eda2011-03-22 13:12:22 +01003137 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3138 if (data) {
3139 struct hci_cp_remote_oob_data_reply cp;
3140
3141 bacpy(&cp.bdaddr, &ev->bdaddr);
3142 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3143 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3144
3145 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3146 &cp);
3147 } else {
3148 struct hci_cp_remote_oob_data_neg_reply cp;
3149
3150 bacpy(&cp.bdaddr, &ev->bdaddr);
3151 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3152 &cp);
3153 }
3154
Szymon Jance1ba1f12011-04-06 13:01:59 +02003155unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003156 hci_dev_unlock(hdev);
3157}
3158
Ville Tervofcd89c02011-02-10 22:38:47 -03003159static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3160{
3161 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3162 struct hci_conn *conn;
3163
3164 BT_DBG("%s status %d", hdev->name, ev->status);
3165
3166 hci_dev_lock(hdev);
3167
3168 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003169 if (!conn) {
3170 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3171 if (!conn) {
3172 BT_ERR("No memory for new connection");
3173 hci_dev_unlock(hdev);
3174 return;
3175 }
Andre Guedes29b79882011-05-31 14:20:54 -03003176
3177 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003178 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003179
3180 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003181 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3182 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003183 hci_proto_connect_cfm(conn, ev->status);
3184 conn->state = BT_CLOSED;
3185 hci_conn_del(conn);
3186 goto unlock;
3187 }
3188
Johan Hedberg48264f02011-11-09 13:58:58 +02003189 mgmt_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003190
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003191 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003192 conn->handle = __le16_to_cpu(ev->handle);
3193 conn->state = BT_CONNECTED;
3194
3195 hci_conn_hold_device(conn);
3196 hci_conn_add_sysfs(conn);
3197
3198 hci_proto_connect_cfm(conn, ev->status);
3199
3200unlock:
3201 hci_dev_unlock(hdev);
3202}
3203
Andre Guedes9aa04c92011-05-26 16:23:51 -03003204static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3205 struct sk_buff *skb)
3206{
Andre Guedese95beb42011-09-26 20:48:35 -03003207 u8 num_reports = skb->data[0];
3208 void *ptr = &skb->data[1];
Andre Guedes9aa04c92011-05-26 16:23:51 -03003209
3210 hci_dev_lock(hdev);
3211
Andre Guedese95beb42011-09-26 20:48:35 -03003212 while (num_reports--) {
3213 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003214
Andre Guedes9aa04c92011-05-26 16:23:51 -03003215 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003216
3217 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003218 }
3219
3220 hci_dev_unlock(hdev);
3221}
3222
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003223static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3224 struct sk_buff *skb)
3225{
3226 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3227 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003228 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003229 struct hci_conn *conn;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003230 struct link_key *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003231
3232 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3233
3234 hci_dev_lock(hdev);
3235
3236 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003237 if (conn == NULL)
3238 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003239
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003240 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3241 if (ltk == NULL)
3242 goto not_found;
3243
3244 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003245 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes726b4ff2011-07-08 18:31:45 -03003246 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003247
3248 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3249
3250 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003251
3252 return;
3253
3254not_found:
3255 neg.handle = ev->handle;
3256 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3257 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003258}
3259
Ville Tervofcd89c02011-02-10 22:38:47 -03003260static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3261{
3262 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3263
3264 skb_pull(skb, sizeof(*le_ev));
3265
3266 switch (le_ev->subevent) {
3267 case HCI_EV_LE_CONN_COMPLETE:
3268 hci_le_conn_complete_evt(hdev, skb);
3269 break;
3270
Andre Guedes9aa04c92011-05-26 16:23:51 -03003271 case HCI_EV_LE_ADVERTISING_REPORT:
3272 hci_le_adv_report_evt(hdev, skb);
3273 break;
3274
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003275 case HCI_EV_LE_LTK_REQ:
3276 hci_le_ltk_request_evt(hdev, skb);
3277 break;
3278
Ville Tervofcd89c02011-02-10 22:38:47 -03003279 default:
3280 break;
3281 }
3282}
3283
Linus Torvalds1da177e2005-04-16 15:20:36 -07003284void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3285{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003286 struct hci_event_hdr *hdr = (void *) skb->data;
3287 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003288
3289 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3290
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003291 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003292 case HCI_EV_INQUIRY_COMPLETE:
3293 hci_inquiry_complete_evt(hdev, skb);
3294 break;
3295
3296 case HCI_EV_INQUIRY_RESULT:
3297 hci_inquiry_result_evt(hdev, skb);
3298 break;
3299
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003300 case HCI_EV_CONN_COMPLETE:
3301 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003302 break;
3303
Linus Torvalds1da177e2005-04-16 15:20:36 -07003304 case HCI_EV_CONN_REQUEST:
3305 hci_conn_request_evt(hdev, skb);
3306 break;
3307
Linus Torvalds1da177e2005-04-16 15:20:36 -07003308 case HCI_EV_DISCONN_COMPLETE:
3309 hci_disconn_complete_evt(hdev, skb);
3310 break;
3311
Linus Torvalds1da177e2005-04-16 15:20:36 -07003312 case HCI_EV_AUTH_COMPLETE:
3313 hci_auth_complete_evt(hdev, skb);
3314 break;
3315
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003316 case HCI_EV_REMOTE_NAME:
3317 hci_remote_name_evt(hdev, skb);
3318 break;
3319
Linus Torvalds1da177e2005-04-16 15:20:36 -07003320 case HCI_EV_ENCRYPT_CHANGE:
3321 hci_encrypt_change_evt(hdev, skb);
3322 break;
3323
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003324 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3325 hci_change_link_key_complete_evt(hdev, skb);
3326 break;
3327
3328 case HCI_EV_REMOTE_FEATURES:
3329 hci_remote_features_evt(hdev, skb);
3330 break;
3331
3332 case HCI_EV_REMOTE_VERSION:
3333 hci_remote_version_evt(hdev, skb);
3334 break;
3335
3336 case HCI_EV_QOS_SETUP_COMPLETE:
3337 hci_qos_setup_complete_evt(hdev, skb);
3338 break;
3339
3340 case HCI_EV_CMD_COMPLETE:
3341 hci_cmd_complete_evt(hdev, skb);
3342 break;
3343
3344 case HCI_EV_CMD_STATUS:
3345 hci_cmd_status_evt(hdev, skb);
3346 break;
3347
3348 case HCI_EV_ROLE_CHANGE:
3349 hci_role_change_evt(hdev, skb);
3350 break;
3351
3352 case HCI_EV_NUM_COMP_PKTS:
3353 hci_num_comp_pkts_evt(hdev, skb);
3354 break;
3355
3356 case HCI_EV_MODE_CHANGE:
3357 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003358 break;
3359
3360 case HCI_EV_PIN_CODE_REQ:
3361 hci_pin_code_request_evt(hdev, skb);
3362 break;
3363
3364 case HCI_EV_LINK_KEY_REQ:
3365 hci_link_key_request_evt(hdev, skb);
3366 break;
3367
3368 case HCI_EV_LINK_KEY_NOTIFY:
3369 hci_link_key_notify_evt(hdev, skb);
3370 break;
3371
3372 case HCI_EV_CLOCK_OFFSET:
3373 hci_clock_offset_evt(hdev, skb);
3374 break;
3375
Marcel Holtmanna8746412008-07-14 20:13:46 +02003376 case HCI_EV_PKT_TYPE_CHANGE:
3377 hci_pkt_type_change_evt(hdev, skb);
3378 break;
3379
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003380 case HCI_EV_PSCAN_REP_MODE:
3381 hci_pscan_rep_mode_evt(hdev, skb);
3382 break;
3383
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003384 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3385 hci_inquiry_result_with_rssi_evt(hdev, skb);
3386 break;
3387
3388 case HCI_EV_REMOTE_EXT_FEATURES:
3389 hci_remote_ext_features_evt(hdev, skb);
3390 break;
3391
3392 case HCI_EV_SYNC_CONN_COMPLETE:
3393 hci_sync_conn_complete_evt(hdev, skb);
3394 break;
3395
3396 case HCI_EV_SYNC_CONN_CHANGED:
3397 hci_sync_conn_changed_evt(hdev, skb);
3398 break;
3399
Marcel Holtmann04837f62006-07-03 10:02:33 +02003400 case HCI_EV_SNIFF_SUBRATE:
3401 hci_sniff_subrate_evt(hdev, skb);
3402 break;
3403
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003404 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3405 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003406 break;
3407
Marcel Holtmann04936842008-07-14 20:13:48 +02003408 case HCI_EV_IO_CAPA_REQUEST:
3409 hci_io_capa_request_evt(hdev, skb);
3410 break;
3411
Johan Hedberg03b555e2011-01-04 15:40:05 +02003412 case HCI_EV_IO_CAPA_REPLY:
3413 hci_io_capa_reply_evt(hdev, skb);
3414 break;
3415
Johan Hedberga5c29682011-02-19 12:05:57 -03003416 case HCI_EV_USER_CONFIRM_REQUEST:
3417 hci_user_confirm_request_evt(hdev, skb);
3418 break;
3419
Brian Gix1143d452011-11-23 08:28:34 -08003420 case HCI_EV_USER_PASSKEY_REQUEST:
3421 hci_user_passkey_request_evt(hdev, skb);
3422 break;
3423
Marcel Holtmann04936842008-07-14 20:13:48 +02003424 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3425 hci_simple_pair_complete_evt(hdev, skb);
3426 break;
3427
Marcel Holtmann41a96212008-07-14 20:13:48 +02003428 case HCI_EV_REMOTE_HOST_FEATURES:
3429 hci_remote_host_features_evt(hdev, skb);
3430 break;
3431
Ville Tervofcd89c02011-02-10 22:38:47 -03003432 case HCI_EV_LE_META:
3433 hci_le_meta_evt(hdev, skb);
3434 break;
3435
Szymon Janc2763eda2011-03-22 13:12:22 +01003436 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3437 hci_remote_oob_data_request_evt(hdev, skb);
3438 break;
3439
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003440 case HCI_EV_NUM_COMP_BLOCKS:
3441 hci_num_comp_blocks_evt(hdev, skb);
3442 break;
3443
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003444 default:
3445 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003446 break;
3447 }
3448
3449 kfree_skb(skb);
3450 hdev->stat.evt_rx++;
3451}
3452
3453/* Generate internal stack event */
3454void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3455{
3456 struct hci_event_hdr *hdr;
3457 struct hci_ev_stack_internal *ev;
3458 struct sk_buff *skb;
3459
3460 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3461 if (!skb)
3462 return;
3463
3464 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3465 hdr->evt = HCI_EV_STACK_INTERNAL;
3466 hdr->plen = sizeof(*ev) + dlen;
3467
3468 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3469 ev->type = type;
3470 memcpy(ev->data, data, dlen);
3471
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003472 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003473 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003474
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003475 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003476 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003477 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003478 kfree_skb(skb);
3479}
Andre Guedese6100a22011-06-30 19:20:54 -03003480
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003481module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003482MODULE_PARM_DESC(enable_le, "Enable LE support");