blob: 42d63522270fc6ce14d624c2e022de22fea00821 [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,
Andre Guedes7d262f82012-01-10 18:20:49 -03001611 info->dev_class, 0, !name_known,
1612 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001614
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615 hci_dev_unlock(hdev);
1616}
1617
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001618static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001620 struct hci_ev_conn_complete *ev = (void *) skb->data;
1621 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001623 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001624
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001626
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001627 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001628 if (!conn) {
1629 if (ev->link_type != SCO_LINK)
1630 goto unlock;
1631
1632 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1633 if (!conn)
1634 goto unlock;
1635
1636 conn->type = SCO_LINK;
1637 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001638
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001639 if (!ev->status) {
1640 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001641
1642 if (conn->type == ACL_LINK) {
1643 conn->state = BT_CONFIG;
1644 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001645 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg48264f02011-11-09 13:58:58 +02001646 mgmt_connected(hdev, &ev->bdaddr, conn->type,
1647 conn->dst_type);
Marcel Holtmann769be972008-07-14 20:13:49 +02001648 } else
1649 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001650
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001651 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001652 hci_conn_add_sysfs(conn);
1653
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001654 if (test_bit(HCI_AUTH, &hdev->flags))
1655 conn->link_mode |= HCI_LM_AUTH;
1656
1657 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1658 conn->link_mode |= HCI_LM_ENCRYPT;
1659
1660 /* Get remote features */
1661 if (conn->type == ACL_LINK) {
1662 struct hci_cp_read_remote_features cp;
1663 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001664 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1665 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001666 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001667
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001668 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001669 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001670 struct hci_cp_change_conn_ptype cp;
1671 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001672 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1673 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1674 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001675 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001676 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001677 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001678 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001679 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001680 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001681 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001682
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001683 if (conn->type == ACL_LINK)
1684 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001685
Marcel Holtmann769be972008-07-14 20:13:49 +02001686 if (ev->status) {
1687 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001688 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001689 } else if (ev->link_type != ACL_LINK)
1690 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001691
1692unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001694
1695 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696}
1697
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1699{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001700 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 int mask = hdev->link_mode;
1702
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001703 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1704 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705
1706 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1707
Szymon Janc138d22e2011-02-17 16:44:23 +01001708 if ((mask & HCI_LM_ACCEPT) &&
1709 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001711 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713
1714 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001715
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001716 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1717 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001718 memcpy(ie->data.dev_class, ev->dev_class, 3);
1719
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1721 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001722 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1723 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001724 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 hci_dev_unlock(hdev);
1726 return;
1727 }
1728 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001729
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 memcpy(conn->dev_class, ev->dev_class, 3);
1731 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001732
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 hci_dev_unlock(hdev);
1734
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001735 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1736 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001738 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001740 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1741 cp.role = 0x00; /* Become master */
1742 else
1743 cp.role = 0x01; /* Remain slave */
1744
1745 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1746 sizeof(cp), &cp);
1747 } else {
1748 struct hci_cp_accept_sync_conn_req cp;
1749
1750 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001751 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001752
1753 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1754 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1755 cp.max_latency = cpu_to_le16(0xffff);
1756 cp.content_format = cpu_to_le16(hdev->voice_setting);
1757 cp.retrans_effort = 0xff;
1758
1759 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1760 sizeof(cp), &cp);
1761 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 } else {
1763 /* Connection rejected */
1764 struct hci_cp_reject_conn_req cp;
1765
1766 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001767 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001768 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769 }
1770}
1771
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1773{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001774 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001775 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776
1777 BT_DBG("%s status %d", hdev->name, ev->status);
1778
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 hci_dev_lock(hdev);
1780
Marcel Holtmann04837f62006-07-03 10:02:33 +02001781 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001782 if (!conn)
1783 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001784
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001785 if (ev->status == 0)
1786 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001788 if (conn->type == ACL_LINK || conn->type == LE_LINK) {
1789 if (ev->status != 0)
1790 mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
1791 else
1792 mgmt_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001793 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001794 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001795
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001796 if (ev->status == 0) {
1797 hci_proto_disconn_cfm(conn, ev->reason);
1798 hci_conn_del(conn);
1799 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001800
1801unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 hci_dev_unlock(hdev);
1803}
1804
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001805static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1806{
1807 struct hci_ev_auth_complete *ev = (void *) skb->data;
1808 struct hci_conn *conn;
1809
1810 BT_DBG("%s status %d", hdev->name, ev->status);
1811
1812 hci_dev_lock(hdev);
1813
1814 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001815 if (!conn)
1816 goto unlock;
1817
1818 if (!ev->status) {
1819 if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) &&
1820 test_bit(HCI_CONN_REAUTH_PEND, &conn->pend)) {
1821 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001822 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001823 conn->link_mode |= HCI_LM_AUTH;
1824 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001825 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001826 } else {
Johan Hedberg744cf192011-11-08 20:40:14 +02001827 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001828 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001829
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001830 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1831 clear_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001832
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001833 if (conn->state == BT_CONFIG) {
1834 if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) {
1835 struct hci_cp_set_conn_encrypt cp;
1836 cp.handle = ev->handle;
1837 cp.encrypt = 0x01;
1838 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1839 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001840 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001841 conn->state = BT_CONNECTED;
1842 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001843 hci_conn_put(conn);
1844 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001845 } else {
1846 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001847
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001848 hci_conn_hold(conn);
1849 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1850 hci_conn_put(conn);
1851 }
1852
1853 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1854 if (!ev->status) {
1855 struct hci_cp_set_conn_encrypt cp;
1856 cp.handle = ev->handle;
1857 cp.encrypt = 0x01;
1858 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1859 &cp);
1860 } else {
1861 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1862 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001863 }
1864 }
1865
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001866unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001867 hci_dev_unlock(hdev);
1868}
1869
1870static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1871{
Johan Hedberg127178d2010-11-18 22:22:29 +02001872 struct hci_ev_remote_name *ev = (void *) skb->data;
1873 struct hci_conn *conn;
1874
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001875 BT_DBG("%s", hdev->name);
1876
1877 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001878
1879 hci_dev_lock(hdev);
1880
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001881 if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001882 if (ev->status == 0)
1883 mgmt_remote_name(hdev, &ev->bdaddr, ev->name);
1884
1885 hci_resolve_next_name(hdev, &ev->bdaddr);
1886 }
Johan Hedberga88a9652011-03-30 13:18:12 +03001887
Johan Hedberg127178d2010-11-18 22:22:29 +02001888 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001889 if (!conn)
1890 goto unlock;
1891
1892 if (!hci_outgoing_auth_needed(hdev, conn))
1893 goto unlock;
1894
1895 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001896 struct hci_cp_auth_requested cp;
1897 cp.handle = __cpu_to_le16(conn->handle);
1898 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1899 }
1900
Johan Hedberg79c6c702011-04-28 11:28:55 -07001901unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001902 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001903}
1904
1905static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1906{
1907 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1908 struct hci_conn *conn;
1909
1910 BT_DBG("%s status %d", hdev->name, ev->status);
1911
1912 hci_dev_lock(hdev);
1913
1914 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1915 if (conn) {
1916 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001917 if (ev->encrypt) {
1918 /* Encryption implies authentication */
1919 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001920 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001921 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001922 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001923 conn->link_mode &= ~HCI_LM_ENCRYPT;
1924 }
1925
1926 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1927
Marcel Holtmannf8558552008-07-14 20:13:49 +02001928 if (conn->state == BT_CONFIG) {
1929 if (!ev->status)
1930 conn->state = BT_CONNECTED;
1931
1932 hci_proto_connect_cfm(conn, ev->status);
1933 hci_conn_put(conn);
1934 } else
1935 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001936 }
1937
1938 hci_dev_unlock(hdev);
1939}
1940
1941static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1942{
1943 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1944 struct hci_conn *conn;
1945
1946 BT_DBG("%s status %d", hdev->name, ev->status);
1947
1948 hci_dev_lock(hdev);
1949
1950 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1951 if (conn) {
1952 if (!ev->status)
1953 conn->link_mode |= HCI_LM_SECURE;
1954
1955 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1956
1957 hci_key_change_cfm(conn, ev->status);
1958 }
1959
1960 hci_dev_unlock(hdev);
1961}
1962
1963static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1964{
1965 struct hci_ev_remote_features *ev = (void *) skb->data;
1966 struct hci_conn *conn;
1967
1968 BT_DBG("%s status %d", hdev->name, ev->status);
1969
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001970 hci_dev_lock(hdev);
1971
1972 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001973 if (!conn)
1974 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001975
Johan Hedbergccd556f2010-11-10 17:11:51 +02001976 if (!ev->status)
1977 memcpy(conn->features, ev->features, 8);
1978
1979 if (conn->state != BT_CONFIG)
1980 goto unlock;
1981
1982 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1983 struct hci_cp_read_remote_ext_features cp;
1984 cp.handle = ev->handle;
1985 cp.page = 0x01;
1986 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001987 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001988 goto unlock;
1989 }
1990
Johan Hedberg127178d2010-11-18 22:22:29 +02001991 if (!ev->status) {
1992 struct hci_cp_remote_name_req cp;
1993 memset(&cp, 0, sizeof(cp));
1994 bacpy(&cp.bdaddr, &conn->dst);
1995 cp.pscan_rep_mode = 0x02;
1996 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1997 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001998
Johan Hedberg127178d2010-11-18 22:22:29 +02001999 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002000 conn->state = BT_CONNECTED;
2001 hci_proto_connect_cfm(conn, ev->status);
2002 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002003 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002004
Johan Hedbergccd556f2010-11-10 17:11:51 +02002005unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002006 hci_dev_unlock(hdev);
2007}
2008
2009static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2010{
2011 BT_DBG("%s", hdev->name);
2012}
2013
2014static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2015{
2016 BT_DBG("%s", hdev->name);
2017}
2018
2019static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2020{
2021 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2022 __u16 opcode;
2023
2024 skb_pull(skb, sizeof(*ev));
2025
2026 opcode = __le16_to_cpu(ev->opcode);
2027
2028 switch (opcode) {
2029 case HCI_OP_INQUIRY_CANCEL:
2030 hci_cc_inquiry_cancel(hdev, skb);
2031 break;
2032
2033 case HCI_OP_EXIT_PERIODIC_INQ:
2034 hci_cc_exit_periodic_inq(hdev, skb);
2035 break;
2036
2037 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2038 hci_cc_remote_name_req_cancel(hdev, skb);
2039 break;
2040
2041 case HCI_OP_ROLE_DISCOVERY:
2042 hci_cc_role_discovery(hdev, skb);
2043 break;
2044
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002045 case HCI_OP_READ_LINK_POLICY:
2046 hci_cc_read_link_policy(hdev, skb);
2047 break;
2048
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002049 case HCI_OP_WRITE_LINK_POLICY:
2050 hci_cc_write_link_policy(hdev, skb);
2051 break;
2052
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002053 case HCI_OP_READ_DEF_LINK_POLICY:
2054 hci_cc_read_def_link_policy(hdev, skb);
2055 break;
2056
2057 case HCI_OP_WRITE_DEF_LINK_POLICY:
2058 hci_cc_write_def_link_policy(hdev, skb);
2059 break;
2060
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002061 case HCI_OP_RESET:
2062 hci_cc_reset(hdev, skb);
2063 break;
2064
2065 case HCI_OP_WRITE_LOCAL_NAME:
2066 hci_cc_write_local_name(hdev, skb);
2067 break;
2068
2069 case HCI_OP_READ_LOCAL_NAME:
2070 hci_cc_read_local_name(hdev, skb);
2071 break;
2072
2073 case HCI_OP_WRITE_AUTH_ENABLE:
2074 hci_cc_write_auth_enable(hdev, skb);
2075 break;
2076
2077 case HCI_OP_WRITE_ENCRYPT_MODE:
2078 hci_cc_write_encrypt_mode(hdev, skb);
2079 break;
2080
2081 case HCI_OP_WRITE_SCAN_ENABLE:
2082 hci_cc_write_scan_enable(hdev, skb);
2083 break;
2084
2085 case HCI_OP_READ_CLASS_OF_DEV:
2086 hci_cc_read_class_of_dev(hdev, skb);
2087 break;
2088
2089 case HCI_OP_WRITE_CLASS_OF_DEV:
2090 hci_cc_write_class_of_dev(hdev, skb);
2091 break;
2092
2093 case HCI_OP_READ_VOICE_SETTING:
2094 hci_cc_read_voice_setting(hdev, skb);
2095 break;
2096
2097 case HCI_OP_WRITE_VOICE_SETTING:
2098 hci_cc_write_voice_setting(hdev, skb);
2099 break;
2100
2101 case HCI_OP_HOST_BUFFER_SIZE:
2102 hci_cc_host_buffer_size(hdev, skb);
2103 break;
2104
Marcel Holtmann333140b2008-07-14 20:13:48 +02002105 case HCI_OP_READ_SSP_MODE:
2106 hci_cc_read_ssp_mode(hdev, skb);
2107 break;
2108
2109 case HCI_OP_WRITE_SSP_MODE:
2110 hci_cc_write_ssp_mode(hdev, skb);
2111 break;
2112
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002113 case HCI_OP_READ_LOCAL_VERSION:
2114 hci_cc_read_local_version(hdev, skb);
2115 break;
2116
2117 case HCI_OP_READ_LOCAL_COMMANDS:
2118 hci_cc_read_local_commands(hdev, skb);
2119 break;
2120
2121 case HCI_OP_READ_LOCAL_FEATURES:
2122 hci_cc_read_local_features(hdev, skb);
2123 break;
2124
Andre Guedes971e3a42011-06-30 19:20:52 -03002125 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2126 hci_cc_read_local_ext_features(hdev, skb);
2127 break;
2128
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002129 case HCI_OP_READ_BUFFER_SIZE:
2130 hci_cc_read_buffer_size(hdev, skb);
2131 break;
2132
2133 case HCI_OP_READ_BD_ADDR:
2134 hci_cc_read_bd_addr(hdev, skb);
2135 break;
2136
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002137 case HCI_OP_READ_DATA_BLOCK_SIZE:
2138 hci_cc_read_data_block_size(hdev, skb);
2139 break;
2140
Johan Hedberg23bb5762010-12-21 23:01:27 +02002141 case HCI_OP_WRITE_CA_TIMEOUT:
2142 hci_cc_write_ca_timeout(hdev, skb);
2143 break;
2144
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002145 case HCI_OP_READ_FLOW_CONTROL_MODE:
2146 hci_cc_read_flow_control_mode(hdev, skb);
2147 break;
2148
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002149 case HCI_OP_READ_LOCAL_AMP_INFO:
2150 hci_cc_read_local_amp_info(hdev, skb);
2151 break;
2152
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002153 case HCI_OP_DELETE_STORED_LINK_KEY:
2154 hci_cc_delete_stored_link_key(hdev, skb);
2155 break;
2156
Johan Hedbergd5859e22011-01-25 01:19:58 +02002157 case HCI_OP_SET_EVENT_MASK:
2158 hci_cc_set_event_mask(hdev, skb);
2159 break;
2160
2161 case HCI_OP_WRITE_INQUIRY_MODE:
2162 hci_cc_write_inquiry_mode(hdev, skb);
2163 break;
2164
2165 case HCI_OP_READ_INQ_RSP_TX_POWER:
2166 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2167 break;
2168
2169 case HCI_OP_SET_EVENT_FLT:
2170 hci_cc_set_event_flt(hdev, skb);
2171 break;
2172
Johan Hedberg980e1a52011-01-22 06:10:07 +02002173 case HCI_OP_PIN_CODE_REPLY:
2174 hci_cc_pin_code_reply(hdev, skb);
2175 break;
2176
2177 case HCI_OP_PIN_CODE_NEG_REPLY:
2178 hci_cc_pin_code_neg_reply(hdev, skb);
2179 break;
2180
Szymon Jancc35938b2011-03-22 13:12:21 +01002181 case HCI_OP_READ_LOCAL_OOB_DATA:
2182 hci_cc_read_local_oob_data_reply(hdev, skb);
2183 break;
2184
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002185 case HCI_OP_LE_READ_BUFFER_SIZE:
2186 hci_cc_le_read_buffer_size(hdev, skb);
2187 break;
2188
Johan Hedberga5c29682011-02-19 12:05:57 -03002189 case HCI_OP_USER_CONFIRM_REPLY:
2190 hci_cc_user_confirm_reply(hdev, skb);
2191 break;
2192
2193 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2194 hci_cc_user_confirm_neg_reply(hdev, skb);
2195 break;
2196
Brian Gix1143d452011-11-23 08:28:34 -08002197 case HCI_OP_USER_PASSKEY_REPLY:
2198 hci_cc_user_passkey_reply(hdev, skb);
2199 break;
2200
2201 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2202 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002203
2204 case HCI_OP_LE_SET_SCAN_PARAM:
2205 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002206 break;
2207
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002208 case HCI_OP_LE_SET_SCAN_ENABLE:
2209 hci_cc_le_set_scan_enable(hdev, skb);
2210 break;
2211
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002212 case HCI_OP_LE_LTK_REPLY:
2213 hci_cc_le_ltk_reply(hdev, skb);
2214 break;
2215
2216 case HCI_OP_LE_LTK_NEG_REPLY:
2217 hci_cc_le_ltk_neg_reply(hdev, skb);
2218 break;
2219
Andre Guedesf9b49302011-06-30 19:20:53 -03002220 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2221 hci_cc_write_le_host_supported(hdev, skb);
2222 break;
2223
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002224 default:
2225 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2226 break;
2227 }
2228
Ville Tervo6bd32322011-02-16 16:32:41 +02002229 if (ev->opcode != HCI_OP_NOP)
2230 del_timer(&hdev->cmd_timer);
2231
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002232 if (ev->ncmd) {
2233 atomic_set(&hdev->cmd_cnt, 1);
2234 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002235 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002236 }
2237}
2238
2239static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2240{
2241 struct hci_ev_cmd_status *ev = (void *) skb->data;
2242 __u16 opcode;
2243
2244 skb_pull(skb, sizeof(*ev));
2245
2246 opcode = __le16_to_cpu(ev->opcode);
2247
2248 switch (opcode) {
2249 case HCI_OP_INQUIRY:
2250 hci_cs_inquiry(hdev, ev->status);
2251 break;
2252
2253 case HCI_OP_CREATE_CONN:
2254 hci_cs_create_conn(hdev, ev->status);
2255 break;
2256
2257 case HCI_OP_ADD_SCO:
2258 hci_cs_add_sco(hdev, ev->status);
2259 break;
2260
Marcel Holtmannf8558552008-07-14 20:13:49 +02002261 case HCI_OP_AUTH_REQUESTED:
2262 hci_cs_auth_requested(hdev, ev->status);
2263 break;
2264
2265 case HCI_OP_SET_CONN_ENCRYPT:
2266 hci_cs_set_conn_encrypt(hdev, ev->status);
2267 break;
2268
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002269 case HCI_OP_REMOTE_NAME_REQ:
2270 hci_cs_remote_name_req(hdev, ev->status);
2271 break;
2272
Marcel Holtmann769be972008-07-14 20:13:49 +02002273 case HCI_OP_READ_REMOTE_FEATURES:
2274 hci_cs_read_remote_features(hdev, ev->status);
2275 break;
2276
2277 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2278 hci_cs_read_remote_ext_features(hdev, ev->status);
2279 break;
2280
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002281 case HCI_OP_SETUP_SYNC_CONN:
2282 hci_cs_setup_sync_conn(hdev, ev->status);
2283 break;
2284
2285 case HCI_OP_SNIFF_MODE:
2286 hci_cs_sniff_mode(hdev, ev->status);
2287 break;
2288
2289 case HCI_OP_EXIT_SNIFF_MODE:
2290 hci_cs_exit_sniff_mode(hdev, ev->status);
2291 break;
2292
Johan Hedberg8962ee72011-01-20 12:40:27 +02002293 case HCI_OP_DISCONNECT:
2294 if (ev->status != 0)
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002295 mgmt_disconnect_failed(hdev, NULL, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002296 break;
2297
Ville Tervofcd89c02011-02-10 22:38:47 -03002298 case HCI_OP_LE_CREATE_CONN:
2299 hci_cs_le_create_conn(hdev, ev->status);
2300 break;
2301
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002302 case HCI_OP_LE_START_ENC:
2303 hci_cs_le_start_enc(hdev, ev->status);
2304 break;
2305
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002306 default:
2307 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2308 break;
2309 }
2310
Ville Tervo6bd32322011-02-16 16:32:41 +02002311 if (ev->opcode != HCI_OP_NOP)
2312 del_timer(&hdev->cmd_timer);
2313
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002314 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002315 atomic_set(&hdev->cmd_cnt, 1);
2316 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002317 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002318 }
2319}
2320
2321static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2322{
2323 struct hci_ev_role_change *ev = (void *) skb->data;
2324 struct hci_conn *conn;
2325
2326 BT_DBG("%s status %d", hdev->name, ev->status);
2327
2328 hci_dev_lock(hdev);
2329
2330 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2331 if (conn) {
2332 if (!ev->status) {
2333 if (ev->role)
2334 conn->link_mode &= ~HCI_LM_MASTER;
2335 else
2336 conn->link_mode |= HCI_LM_MASTER;
2337 }
2338
2339 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
2340
2341 hci_role_switch_cfm(conn, ev->status, ev->role);
2342 }
2343
2344 hci_dev_unlock(hdev);
2345}
2346
Linus Torvalds1da177e2005-04-16 15:20:36 -07002347static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2348{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002349 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002350 int i;
2351
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002352 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2353 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2354 return;
2355 }
2356
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002357 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2358 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002359 BT_DBG("%s bad parameters", hdev->name);
2360 return;
2361 }
2362
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002363 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2364
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002365 for (i = 0; i < ev->num_hndl; i++) {
2366 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002367 struct hci_conn *conn;
2368 __u16 handle, count;
2369
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002370 handle = __le16_to_cpu(info->handle);
2371 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372
2373 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002374 if (!conn)
2375 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002377 conn->sent -= count;
2378
2379 switch (conn->type) {
2380 case ACL_LINK:
2381 hdev->acl_cnt += count;
2382 if (hdev->acl_cnt > hdev->acl_pkts)
2383 hdev->acl_cnt = hdev->acl_pkts;
2384 break;
2385
2386 case LE_LINK:
2387 if (hdev->le_pkts) {
2388 hdev->le_cnt += count;
2389 if (hdev->le_cnt > hdev->le_pkts)
2390 hdev->le_cnt = hdev->le_pkts;
2391 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002392 hdev->acl_cnt += count;
2393 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394 hdev->acl_cnt = hdev->acl_pkts;
2395 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002396 break;
2397
2398 case SCO_LINK:
2399 hdev->sco_cnt += count;
2400 if (hdev->sco_cnt > hdev->sco_pkts)
2401 hdev->sco_cnt = hdev->sco_pkts;
2402 break;
2403
2404 default:
2405 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2406 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002407 }
2408 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002409
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002410 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411}
2412
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002413static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2414 struct sk_buff *skb)
2415{
2416 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2417 int i;
2418
2419 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2420 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2421 return;
2422 }
2423
2424 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2425 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2426 BT_DBG("%s bad parameters", hdev->name);
2427 return;
2428 }
2429
2430 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2431 ev->num_hndl);
2432
2433 for (i = 0; i < ev->num_hndl; i++) {
2434 struct hci_comp_blocks_info *info = &ev->handles[i];
2435 struct hci_conn *conn;
2436 __u16 handle, block_count;
2437
2438 handle = __le16_to_cpu(info->handle);
2439 block_count = __le16_to_cpu(info->blocks);
2440
2441 conn = hci_conn_hash_lookup_handle(hdev, handle);
2442 if (!conn)
2443 continue;
2444
2445 conn->sent -= block_count;
2446
2447 switch (conn->type) {
2448 case ACL_LINK:
2449 hdev->block_cnt += block_count;
2450 if (hdev->block_cnt > hdev->num_blocks)
2451 hdev->block_cnt = hdev->num_blocks;
2452 break;
2453
2454 default:
2455 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2456 break;
2457 }
2458 }
2459
2460 queue_work(hdev->workqueue, &hdev->tx_work);
2461}
2462
Marcel Holtmann04837f62006-07-03 10:02:33 +02002463static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002464{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002465 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002466 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002467
2468 BT_DBG("%s status %d", hdev->name, ev->status);
2469
2470 hci_dev_lock(hdev);
2471
Marcel Holtmann04837f62006-07-03 10:02:33 +02002472 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2473 if (conn) {
2474 conn->mode = ev->mode;
2475 conn->interval = __le16_to_cpu(ev->interval);
2476
2477 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
2478 if (conn->mode == HCI_CM_ACTIVE)
2479 conn->power_save = 1;
2480 else
2481 conn->power_save = 0;
2482 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002483
2484 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
2485 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002486 }
2487
2488 hci_dev_unlock(hdev);
2489}
2490
Linus Torvalds1da177e2005-04-16 15:20:36 -07002491static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2492{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002493 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2494 struct hci_conn *conn;
2495
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002496 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002497
2498 hci_dev_lock(hdev);
2499
2500 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002501 if (!conn)
2502 goto unlock;
2503
2504 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002505 hci_conn_hold(conn);
2506 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2507 hci_conn_put(conn);
2508 }
2509
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002510 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002511 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2512 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002513 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002514 u8 secure;
2515
2516 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2517 secure = 1;
2518 else
2519 secure = 0;
2520
Johan Hedberg744cf192011-11-08 20:40:14 +02002521 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002522 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002523
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002524unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002525 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526}
2527
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2529{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002530 struct hci_ev_link_key_req *ev = (void *) skb->data;
2531 struct hci_cp_link_key_reply cp;
2532 struct hci_conn *conn;
2533 struct link_key *key;
2534
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002535 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002536
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002537 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002538 return;
2539
2540 hci_dev_lock(hdev);
2541
2542 key = hci_find_link_key(hdev, &ev->bdaddr);
2543 if (!key) {
2544 BT_DBG("%s link key not found for %s", hdev->name,
2545 batostr(&ev->bdaddr));
2546 goto not_found;
2547 }
2548
2549 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2550 batostr(&ev->bdaddr));
2551
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002552 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002553 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002554 BT_DBG("%s ignoring debug key", hdev->name);
2555 goto not_found;
2556 }
2557
2558 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002559 if (conn) {
2560 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2561 conn->auth_type != 0xff &&
2562 (conn->auth_type & 0x01)) {
2563 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2564 goto not_found;
2565 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002566
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002567 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2568 conn->pending_sec_level == BT_SECURITY_HIGH) {
2569 BT_DBG("%s ignoring key unauthenticated for high \
2570 security", hdev->name);
2571 goto not_found;
2572 }
2573
2574 conn->key_type = key->type;
2575 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002576 }
2577
2578 bacpy(&cp.bdaddr, &ev->bdaddr);
2579 memcpy(cp.link_key, key->val, 16);
2580
2581 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2582
2583 hci_dev_unlock(hdev);
2584
2585 return;
2586
2587not_found:
2588 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2589 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002590}
2591
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2593{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002594 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2595 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002596 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002597
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002598 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002599
2600 hci_dev_lock(hdev);
2601
2602 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2603 if (conn) {
2604 hci_conn_hold(conn);
2605 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002606 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002607
2608 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2609 conn->key_type = ev->key_type;
2610
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002611 hci_conn_put(conn);
2612 }
2613
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002614 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002615 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002616 ev->key_type, pin_len);
2617
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002618 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619}
2620
Marcel Holtmann04837f62006-07-03 10:02:33 +02002621static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2622{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002623 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002624 struct hci_conn *conn;
2625
2626 BT_DBG("%s status %d", hdev->name, ev->status);
2627
2628 hci_dev_lock(hdev);
2629
2630 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002631 if (conn && !ev->status) {
2632 struct inquiry_entry *ie;
2633
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002634 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2635 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636 ie->data.clock_offset = ev->clock_offset;
2637 ie->timestamp = jiffies;
2638 }
2639 }
2640
2641 hci_dev_unlock(hdev);
2642}
2643
Marcel Holtmanna8746412008-07-14 20:13:46 +02002644static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2645{
2646 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2647 struct hci_conn *conn;
2648
2649 BT_DBG("%s status %d", hdev->name, ev->status);
2650
2651 hci_dev_lock(hdev);
2652
2653 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2654 if (conn && !ev->status)
2655 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2656
2657 hci_dev_unlock(hdev);
2658}
2659
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002660static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2661{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002662 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002663 struct inquiry_entry *ie;
2664
2665 BT_DBG("%s", hdev->name);
2666
2667 hci_dev_lock(hdev);
2668
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002669 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2670 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002671 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2672 ie->timestamp = jiffies;
2673 }
2674
2675 hci_dev_unlock(hdev);
2676}
2677
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002678static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2679{
2680 struct inquiry_data data;
2681 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg31754052012-01-04 13:39:52 +02002682 bool name_known;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002683
2684 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2685
2686 if (!num_rsp)
2687 return;
2688
2689 hci_dev_lock(hdev);
2690
2691 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002692 struct inquiry_info_with_rssi_and_pscan_mode *info;
2693 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002694
Johan Hedberge17acd42011-03-30 23:57:16 +03002695 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002696 bacpy(&data.bdaddr, &info->bdaddr);
2697 data.pscan_rep_mode = info->pscan_rep_mode;
2698 data.pscan_period_mode = info->pscan_period_mode;
2699 data.pscan_mode = info->pscan_mode;
2700 memcpy(data.dev_class, info->dev_class, 3);
2701 data.clock_offset = info->clock_offset;
2702 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002703 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002704
2705 name_known = hci_inquiry_cache_update(hdev, &data,
2706 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002707 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002708 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002709 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002710 }
2711 } else {
2712 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2713
Johan Hedberge17acd42011-03-30 23:57:16 +03002714 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002715 bacpy(&data.bdaddr, &info->bdaddr);
2716 data.pscan_rep_mode = info->pscan_rep_mode;
2717 data.pscan_period_mode = info->pscan_period_mode;
2718 data.pscan_mode = 0x00;
2719 memcpy(data.dev_class, info->dev_class, 3);
2720 data.clock_offset = info->clock_offset;
2721 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002722 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002723 name_known = hci_inquiry_cache_update(hdev, &data,
2724 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002725 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002726 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002727 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002728 }
2729 }
2730
2731 hci_dev_unlock(hdev);
2732}
2733
2734static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2735{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002736 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2737 struct hci_conn *conn;
2738
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002739 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002740
Marcel Holtmann41a96212008-07-14 20:13:48 +02002741 hci_dev_lock(hdev);
2742
2743 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002744 if (!conn)
2745 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002746
Johan Hedbergccd556f2010-11-10 17:11:51 +02002747 if (!ev->status && ev->page == 0x01) {
2748 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002749
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002750 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2751 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002752 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002753
Johan Hedbergccd556f2010-11-10 17:11:51 +02002754 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002755 }
2756
Johan Hedbergccd556f2010-11-10 17:11:51 +02002757 if (conn->state != BT_CONFIG)
2758 goto unlock;
2759
Johan Hedberg127178d2010-11-18 22:22:29 +02002760 if (!ev->status) {
2761 struct hci_cp_remote_name_req cp;
2762 memset(&cp, 0, sizeof(cp));
2763 bacpy(&cp.bdaddr, &conn->dst);
2764 cp.pscan_rep_mode = 0x02;
2765 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2766 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002767
Johan Hedberg127178d2010-11-18 22:22:29 +02002768 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002769 conn->state = BT_CONNECTED;
2770 hci_proto_connect_cfm(conn, ev->status);
2771 hci_conn_put(conn);
2772 }
2773
2774unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002775 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002776}
2777
2778static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2779{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002780 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2781 struct hci_conn *conn;
2782
2783 BT_DBG("%s status %d", hdev->name, ev->status);
2784
2785 hci_dev_lock(hdev);
2786
2787 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002788 if (!conn) {
2789 if (ev->link_type == ESCO_LINK)
2790 goto unlock;
2791
2792 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2793 if (!conn)
2794 goto unlock;
2795
2796 conn->type = SCO_LINK;
2797 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002798
Marcel Holtmann732547f2009-04-19 19:14:14 +02002799 switch (ev->status) {
2800 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002801 conn->handle = __le16_to_cpu(ev->handle);
2802 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002803
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002804 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002805 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002806 break;
2807
Stephen Coe705e5712010-02-16 11:29:44 -05002808 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002809 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002810 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002811 case 0x1f: /* Unspecified error */
2812 if (conn->out && conn->attempt < 2) {
2813 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2814 (hdev->esco_type & EDR_ESCO_MASK);
2815 hci_setup_sync(conn, conn->link->handle);
2816 goto unlock;
2817 }
2818 /* fall through */
2819
2820 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002821 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002822 break;
2823 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002824
2825 hci_proto_connect_cfm(conn, ev->status);
2826 if (ev->status)
2827 hci_conn_del(conn);
2828
2829unlock:
2830 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002831}
2832
2833static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2834{
2835 BT_DBG("%s", hdev->name);
2836}
2837
Marcel Holtmann04837f62006-07-03 10:02:33 +02002838static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2839{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002840 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002841
2842 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002843}
2844
Johan Hedberg561aafb2012-01-04 13:31:59 +02002845static inline bool eir_has_complete_name(u8 *data, size_t data_len)
2846{
2847 u8 field_len;
2848 size_t parsed;
2849
2850 for (parsed = 0; parsed < data_len - 1; parsed += field_len) {
2851 field_len = data[0];
2852
2853 if (field_len == 0)
2854 break;
2855
2856 parsed += field_len + 1;
2857
2858 if (parsed > data_len)
2859 break;
2860
2861 if (data[1] == EIR_NAME_COMPLETE)
2862 return true;
2863
2864 data += field_len + 1;
2865 }
2866
2867 return false;
2868}
2869
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002870static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2871{
2872 struct inquiry_data data;
2873 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2874 int num_rsp = *((__u8 *) skb->data);
2875
2876 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2877
2878 if (!num_rsp)
2879 return;
2880
2881 hci_dev_lock(hdev);
2882
Johan Hedberge17acd42011-03-30 23:57:16 +03002883 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg561aafb2012-01-04 13:31:59 +02002884 bool name_known;
2885
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002886 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002887 data.pscan_rep_mode = info->pscan_rep_mode;
2888 data.pscan_period_mode = info->pscan_period_mode;
2889 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002890 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002891 data.clock_offset = info->clock_offset;
2892 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002893 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002894
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002895 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg561aafb2012-01-04 13:31:59 +02002896 name_known = eir_has_complete_name(info->data,
2897 sizeof(info->data));
2898 else
2899 name_known = true;
2900
Johan Hedberg31754052012-01-04 13:39:52 +02002901 name_known = hci_inquiry_cache_update(hdev, &data, name_known);
Johan Hedberg48264f02011-11-09 13:58:58 +02002902 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002903 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002904 !name_known, info->data,
2905 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002906 }
2907
2908 hci_dev_unlock(hdev);
2909}
2910
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002911static inline u8 hci_get_auth_req(struct hci_conn *conn)
2912{
2913 /* If remote requests dedicated bonding follow that lead */
2914 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2915 /* If both remote and local IO capabilities allow MITM
2916 * protection then require it, otherwise don't */
2917 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2918 return 0x02;
2919 else
2920 return 0x03;
2921 }
2922
2923 /* If remote requests no-bonding follow that lead */
2924 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002925 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002926
2927 return conn->auth_type;
2928}
2929
Marcel Holtmann04936842008-07-14 20:13:48 +02002930static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2931{
2932 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2933 struct hci_conn *conn;
2934
2935 BT_DBG("%s", hdev->name);
2936
2937 hci_dev_lock(hdev);
2938
2939 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002940 if (!conn)
2941 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002942
Johan Hedberg03b555e2011-01-04 15:40:05 +02002943 hci_conn_hold(conn);
2944
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002945 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002946 goto unlock;
2947
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002948 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02002949 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002950 struct hci_cp_io_capability_reply cp;
2951
2952 bacpy(&cp.bdaddr, &ev->bdaddr);
2953 cp.capability = conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07002954 conn->auth_type = hci_get_auth_req(conn);
2955 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002956
Szymon Jancce85ee12011-03-22 13:12:23 +01002957 if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
2958 hci_find_remote_oob_data(hdev, &conn->dst))
2959 cp.oob_data = 0x01;
2960 else
2961 cp.oob_data = 0x00;
2962
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002963 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2964 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002965 } else {
2966 struct hci_cp_io_capability_neg_reply cp;
2967
2968 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002969 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02002970
2971 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2972 sizeof(cp), &cp);
2973 }
2974
2975unlock:
2976 hci_dev_unlock(hdev);
2977}
2978
2979static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2980{
2981 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2982 struct hci_conn *conn;
2983
2984 BT_DBG("%s", hdev->name);
2985
2986 hci_dev_lock(hdev);
2987
2988 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2989 if (!conn)
2990 goto unlock;
2991
Johan Hedberg03b555e2011-01-04 15:40:05 +02002992 conn->remote_cap = ev->capability;
2993 conn->remote_oob = ev->oob_data;
2994 conn->remote_auth = ev->authentication;
2995
2996unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002997 hci_dev_unlock(hdev);
2998}
2999
Johan Hedberga5c29682011-02-19 12:05:57 -03003000static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3001 struct sk_buff *skb)
3002{
3003 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003004 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003005 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003006
3007 BT_DBG("%s", hdev->name);
3008
3009 hci_dev_lock(hdev);
3010
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003011 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003012 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003013
Johan Hedberg7a828902011-04-28 11:28:53 -07003014 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3015 if (!conn)
3016 goto unlock;
3017
3018 loc_mitm = (conn->auth_type & 0x01);
3019 rem_mitm = (conn->remote_auth & 0x01);
3020
3021 /* If we require MITM but the remote device can't provide that
3022 * (it has NoInputNoOutput) then reject the confirmation
3023 * request. The only exception is when we're dedicated bonding
3024 * initiators (connect_cfm_cb set) since then we always have the MITM
3025 * bit set. */
3026 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3027 BT_DBG("Rejecting request: remote device can't provide MITM");
3028 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3029 sizeof(ev->bdaddr), &ev->bdaddr);
3030 goto unlock;
3031 }
3032
3033 /* If no side requires MITM protection; auto-accept */
3034 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3035 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003036
3037 /* If we're not the initiators request authorization to
3038 * proceed from user space (mgmt_user_confirm with
3039 * confirm_hint set to 1). */
3040 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
3041 BT_DBG("Confirming auto-accept as acceptor");
3042 confirm_hint = 1;
3043 goto confirm;
3044 }
3045
Johan Hedberg9f616562011-04-28 11:28:54 -07003046 BT_DBG("Auto-accept of user confirmation with %ums delay",
3047 hdev->auto_accept_delay);
3048
3049 if (hdev->auto_accept_delay > 0) {
3050 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3051 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3052 goto unlock;
3053 }
3054
Johan Hedberg7a828902011-04-28 11:28:53 -07003055 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3056 sizeof(ev->bdaddr), &ev->bdaddr);
3057 goto unlock;
3058 }
3059
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003060confirm:
Johan Hedberg744cf192011-11-08 20:40:14 +02003061 mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003062 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003063
3064unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003065 hci_dev_unlock(hdev);
3066}
3067
Brian Gix1143d452011-11-23 08:28:34 -08003068static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3069 struct sk_buff *skb)
3070{
3071 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3072
3073 BT_DBG("%s", hdev->name);
3074
3075 hci_dev_lock(hdev);
3076
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003077 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08003078 mgmt_user_passkey_request(hdev, &ev->bdaddr);
3079
3080 hci_dev_unlock(hdev);
3081}
3082
Marcel Holtmann04936842008-07-14 20:13:48 +02003083static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3084{
3085 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3086 struct hci_conn *conn;
3087
3088 BT_DBG("%s", hdev->name);
3089
3090 hci_dev_lock(hdev);
3091
3092 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003093 if (!conn)
3094 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003095
Johan Hedberg2a611692011-02-19 12:06:00 -03003096 /* To avoid duplicate auth_failed events to user space we check
3097 * the HCI_CONN_AUTH_PEND flag which will be set if we
3098 * initiated the authentication. A traditional auth_complete
3099 * event gets always produced as initiator and is also mapped to
3100 * the mgmt_auth_failed event */
3101 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
Johan Hedberg744cf192011-11-08 20:40:14 +02003102 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003103
3104 hci_conn_put(conn);
3105
3106unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003107 hci_dev_unlock(hdev);
3108}
3109
Marcel Holtmann41a96212008-07-14 20:13:48 +02003110static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3111{
3112 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3113 struct inquiry_entry *ie;
3114
3115 BT_DBG("%s", hdev->name);
3116
3117 hci_dev_lock(hdev);
3118
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003119 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3120 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003121 ie->data.ssp_mode = (ev->features[0] & 0x01);
3122
3123 hci_dev_unlock(hdev);
3124}
3125
Szymon Janc2763eda2011-03-22 13:12:22 +01003126static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3127 struct sk_buff *skb)
3128{
3129 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3130 struct oob_data *data;
3131
3132 BT_DBG("%s", hdev->name);
3133
3134 hci_dev_lock(hdev);
3135
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003136 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003137 goto unlock;
3138
Szymon Janc2763eda2011-03-22 13:12:22 +01003139 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3140 if (data) {
3141 struct hci_cp_remote_oob_data_reply cp;
3142
3143 bacpy(&cp.bdaddr, &ev->bdaddr);
3144 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3145 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3146
3147 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3148 &cp);
3149 } else {
3150 struct hci_cp_remote_oob_data_neg_reply cp;
3151
3152 bacpy(&cp.bdaddr, &ev->bdaddr);
3153 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3154 &cp);
3155 }
3156
Szymon Jance1ba1f12011-04-06 13:01:59 +02003157unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003158 hci_dev_unlock(hdev);
3159}
3160
Ville Tervofcd89c02011-02-10 22:38:47 -03003161static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3162{
3163 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3164 struct hci_conn *conn;
3165
3166 BT_DBG("%s status %d", hdev->name, ev->status);
3167
3168 hci_dev_lock(hdev);
3169
3170 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003171 if (!conn) {
3172 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3173 if (!conn) {
3174 BT_ERR("No memory for new connection");
3175 hci_dev_unlock(hdev);
3176 return;
3177 }
Andre Guedes29b79882011-05-31 14:20:54 -03003178
3179 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003180 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003181
3182 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003183 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3184 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003185 hci_proto_connect_cfm(conn, ev->status);
3186 conn->state = BT_CLOSED;
3187 hci_conn_del(conn);
3188 goto unlock;
3189 }
3190
Johan Hedberg48264f02011-11-09 13:58:58 +02003191 mgmt_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003192
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003193 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003194 conn->handle = __le16_to_cpu(ev->handle);
3195 conn->state = BT_CONNECTED;
3196
3197 hci_conn_hold_device(conn);
3198 hci_conn_add_sysfs(conn);
3199
3200 hci_proto_connect_cfm(conn, ev->status);
3201
3202unlock:
3203 hci_dev_unlock(hdev);
3204}
3205
Andre Guedes9aa04c92011-05-26 16:23:51 -03003206static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3207 struct sk_buff *skb)
3208{
Andre Guedese95beb42011-09-26 20:48:35 -03003209 u8 num_reports = skb->data[0];
3210 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003211 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003212
3213 hci_dev_lock(hdev);
3214
Andre Guedese95beb42011-09-26 20:48:35 -03003215 while (num_reports--) {
3216 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003217
Andre Guedes9aa04c92011-05-26 16:23:51 -03003218 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003219
Andre Guedes3c9e9192012-01-10 18:20:50 -03003220 rssi = ev->data[ev->length];
3221 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3222 NULL, rssi, 0, ev->data, ev->length);
3223
Andre Guedese95beb42011-09-26 20:48:35 -03003224 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003225 }
3226
3227 hci_dev_unlock(hdev);
3228}
3229
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003230static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3231 struct sk_buff *skb)
3232{
3233 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3234 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003235 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003236 struct hci_conn *conn;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003237 struct link_key *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003238
3239 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3240
3241 hci_dev_lock(hdev);
3242
3243 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003244 if (conn == NULL)
3245 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003246
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003247 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3248 if (ltk == NULL)
3249 goto not_found;
3250
3251 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003252 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes726b4ff2011-07-08 18:31:45 -03003253 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003254
3255 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3256
3257 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003258
3259 return;
3260
3261not_found:
3262 neg.handle = ev->handle;
3263 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3264 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003265}
3266
Ville Tervofcd89c02011-02-10 22:38:47 -03003267static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3268{
3269 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3270
3271 skb_pull(skb, sizeof(*le_ev));
3272
3273 switch (le_ev->subevent) {
3274 case HCI_EV_LE_CONN_COMPLETE:
3275 hci_le_conn_complete_evt(hdev, skb);
3276 break;
3277
Andre Guedes9aa04c92011-05-26 16:23:51 -03003278 case HCI_EV_LE_ADVERTISING_REPORT:
3279 hci_le_adv_report_evt(hdev, skb);
3280 break;
3281
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003282 case HCI_EV_LE_LTK_REQ:
3283 hci_le_ltk_request_evt(hdev, skb);
3284 break;
3285
Ville Tervofcd89c02011-02-10 22:38:47 -03003286 default:
3287 break;
3288 }
3289}
3290
Linus Torvalds1da177e2005-04-16 15:20:36 -07003291void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3292{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003293 struct hci_event_hdr *hdr = (void *) skb->data;
3294 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003295
3296 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3297
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003298 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003299 case HCI_EV_INQUIRY_COMPLETE:
3300 hci_inquiry_complete_evt(hdev, skb);
3301 break;
3302
3303 case HCI_EV_INQUIRY_RESULT:
3304 hci_inquiry_result_evt(hdev, skb);
3305 break;
3306
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003307 case HCI_EV_CONN_COMPLETE:
3308 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003309 break;
3310
Linus Torvalds1da177e2005-04-16 15:20:36 -07003311 case HCI_EV_CONN_REQUEST:
3312 hci_conn_request_evt(hdev, skb);
3313 break;
3314
Linus Torvalds1da177e2005-04-16 15:20:36 -07003315 case HCI_EV_DISCONN_COMPLETE:
3316 hci_disconn_complete_evt(hdev, skb);
3317 break;
3318
Linus Torvalds1da177e2005-04-16 15:20:36 -07003319 case HCI_EV_AUTH_COMPLETE:
3320 hci_auth_complete_evt(hdev, skb);
3321 break;
3322
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003323 case HCI_EV_REMOTE_NAME:
3324 hci_remote_name_evt(hdev, skb);
3325 break;
3326
Linus Torvalds1da177e2005-04-16 15:20:36 -07003327 case HCI_EV_ENCRYPT_CHANGE:
3328 hci_encrypt_change_evt(hdev, skb);
3329 break;
3330
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003331 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3332 hci_change_link_key_complete_evt(hdev, skb);
3333 break;
3334
3335 case HCI_EV_REMOTE_FEATURES:
3336 hci_remote_features_evt(hdev, skb);
3337 break;
3338
3339 case HCI_EV_REMOTE_VERSION:
3340 hci_remote_version_evt(hdev, skb);
3341 break;
3342
3343 case HCI_EV_QOS_SETUP_COMPLETE:
3344 hci_qos_setup_complete_evt(hdev, skb);
3345 break;
3346
3347 case HCI_EV_CMD_COMPLETE:
3348 hci_cmd_complete_evt(hdev, skb);
3349 break;
3350
3351 case HCI_EV_CMD_STATUS:
3352 hci_cmd_status_evt(hdev, skb);
3353 break;
3354
3355 case HCI_EV_ROLE_CHANGE:
3356 hci_role_change_evt(hdev, skb);
3357 break;
3358
3359 case HCI_EV_NUM_COMP_PKTS:
3360 hci_num_comp_pkts_evt(hdev, skb);
3361 break;
3362
3363 case HCI_EV_MODE_CHANGE:
3364 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003365 break;
3366
3367 case HCI_EV_PIN_CODE_REQ:
3368 hci_pin_code_request_evt(hdev, skb);
3369 break;
3370
3371 case HCI_EV_LINK_KEY_REQ:
3372 hci_link_key_request_evt(hdev, skb);
3373 break;
3374
3375 case HCI_EV_LINK_KEY_NOTIFY:
3376 hci_link_key_notify_evt(hdev, skb);
3377 break;
3378
3379 case HCI_EV_CLOCK_OFFSET:
3380 hci_clock_offset_evt(hdev, skb);
3381 break;
3382
Marcel Holtmanna8746412008-07-14 20:13:46 +02003383 case HCI_EV_PKT_TYPE_CHANGE:
3384 hci_pkt_type_change_evt(hdev, skb);
3385 break;
3386
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003387 case HCI_EV_PSCAN_REP_MODE:
3388 hci_pscan_rep_mode_evt(hdev, skb);
3389 break;
3390
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003391 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3392 hci_inquiry_result_with_rssi_evt(hdev, skb);
3393 break;
3394
3395 case HCI_EV_REMOTE_EXT_FEATURES:
3396 hci_remote_ext_features_evt(hdev, skb);
3397 break;
3398
3399 case HCI_EV_SYNC_CONN_COMPLETE:
3400 hci_sync_conn_complete_evt(hdev, skb);
3401 break;
3402
3403 case HCI_EV_SYNC_CONN_CHANGED:
3404 hci_sync_conn_changed_evt(hdev, skb);
3405 break;
3406
Marcel Holtmann04837f62006-07-03 10:02:33 +02003407 case HCI_EV_SNIFF_SUBRATE:
3408 hci_sniff_subrate_evt(hdev, skb);
3409 break;
3410
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003411 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3412 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003413 break;
3414
Marcel Holtmann04936842008-07-14 20:13:48 +02003415 case HCI_EV_IO_CAPA_REQUEST:
3416 hci_io_capa_request_evt(hdev, skb);
3417 break;
3418
Johan Hedberg03b555e2011-01-04 15:40:05 +02003419 case HCI_EV_IO_CAPA_REPLY:
3420 hci_io_capa_reply_evt(hdev, skb);
3421 break;
3422
Johan Hedberga5c29682011-02-19 12:05:57 -03003423 case HCI_EV_USER_CONFIRM_REQUEST:
3424 hci_user_confirm_request_evt(hdev, skb);
3425 break;
3426
Brian Gix1143d452011-11-23 08:28:34 -08003427 case HCI_EV_USER_PASSKEY_REQUEST:
3428 hci_user_passkey_request_evt(hdev, skb);
3429 break;
3430
Marcel Holtmann04936842008-07-14 20:13:48 +02003431 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3432 hci_simple_pair_complete_evt(hdev, skb);
3433 break;
3434
Marcel Holtmann41a96212008-07-14 20:13:48 +02003435 case HCI_EV_REMOTE_HOST_FEATURES:
3436 hci_remote_host_features_evt(hdev, skb);
3437 break;
3438
Ville Tervofcd89c02011-02-10 22:38:47 -03003439 case HCI_EV_LE_META:
3440 hci_le_meta_evt(hdev, skb);
3441 break;
3442
Szymon Janc2763eda2011-03-22 13:12:22 +01003443 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3444 hci_remote_oob_data_request_evt(hdev, skb);
3445 break;
3446
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003447 case HCI_EV_NUM_COMP_BLOCKS:
3448 hci_num_comp_blocks_evt(hdev, skb);
3449 break;
3450
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003451 default:
3452 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003453 break;
3454 }
3455
3456 kfree_skb(skb);
3457 hdev->stat.evt_rx++;
3458}
3459
3460/* Generate internal stack event */
3461void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3462{
3463 struct hci_event_hdr *hdr;
3464 struct hci_ev_stack_internal *ev;
3465 struct sk_buff *skb;
3466
3467 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3468 if (!skb)
3469 return;
3470
3471 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3472 hdr->evt = HCI_EV_STACK_INTERNAL;
3473 hdr->plen = sizeof(*ev) + dlen;
3474
3475 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3476 ev->type = type;
3477 memcpy(ev->data, data, dlen);
3478
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003479 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003480 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003481
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003482 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003483 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003484 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003485 kfree_skb(skb);
3486}
Andre Guedese6100a22011-06-30 19:20:54 -03003487
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003488module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003489MODULE_PARM_DESC(enable_le, "Enable LE support");