blob: eb198ccbc10d92f594fc77ea07e218fd7717e018 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
38#include <linux/notifier.h>
39#include <net/sock.h>
40
41#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020042#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <asm/unaligned.h>
44
45#include <net/bluetooth/bluetooth.h>
46#include <net/bluetooth/hci_core.h>
47
Rusty Russelleb939922011-12-19 14:08:01 +000048static bool enable_le;
Andre Guedese6100a22011-06-30 19:20:54 -030049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050/* Handle HCI Event packets */
51
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070053{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020054 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Marcel Holtmanna9de9242007-10-20 13:33:56 +020056 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Andre Guedese6d465c2011-11-09 17:14:26 -030058 if (status) {
59 hci_dev_lock(hdev);
60 mgmt_stop_discovery_failed(hdev, status);
61 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020062 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030063 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Andre Guedes89352e72011-11-04 14:16:53 -030065 clear_bit(HCI_INQUIRY, &hdev->flags);
66
Johan Hedberg56e5cb82011-11-08 20:40:16 +020067 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020068 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020069 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010070
Johan Hedberg23bb5762010-12-21 23:01:27 +020071 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010072
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070074}
75
Marcel Holtmanna9de9242007-10-20 13:33:56 +020076static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070077{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020078 __u8 status = *((__u8 *) skb->data);
79
80 BT_DBG("%s status 0x%x", hdev->name, status);
81
82 if (status)
83 return;
84
Marcel Holtmanna9de9242007-10-20 13:33:56 +020085 hci_conn_check_pending(hdev);
86}
87
88static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
89{
90 BT_DBG("%s", hdev->name);
91}
92
93static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
94{
95 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Marcel Holtmanna9de9242007-10-20 13:33:56 +020098 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 if (rp->status)
101 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200103 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
106 if (conn) {
107 if (rp->role)
108 conn->link_mode &= ~HCI_LM_MASTER;
109 else
110 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200112
113 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114}
115
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200116static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
117{
118 struct hci_rp_read_link_policy *rp = (void *) skb->data;
119 struct hci_conn *conn;
120
121 BT_DBG("%s status 0x%x", hdev->name, rp->status);
122
123 if (rp->status)
124 return;
125
126 hci_dev_lock(hdev);
127
128 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
129 if (conn)
130 conn->link_policy = __le16_to_cpu(rp->policy);
131
132 hci_dev_unlock(hdev);
133}
134
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200137 struct hci_rp_write_link_policy *rp = (void *) skb->data;
138 struct hci_conn *conn;
139 void *sent;
140
141 BT_DBG("%s status 0x%x", hdev->name, rp->status);
142
143 if (rp->status)
144 return;
145
146 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
147 if (!sent)
148 return;
149
150 hci_dev_lock(hdev);
151
152 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200153 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700154 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200155
156 hci_dev_unlock(hdev);
157}
158
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200159static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
160{
161 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
162
163 BT_DBG("%s status 0x%x", hdev->name, rp->status);
164
165 if (rp->status)
166 return;
167
168 hdev->link_policy = __le16_to_cpu(rp->policy);
169}
170
171static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
172{
173 __u8 status = *((__u8 *) skb->data);
174 void *sent;
175
176 BT_DBG("%s status 0x%x", hdev->name, status);
177
178 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
179 if (!sent)
180 return;
181
182 if (!status)
183 hdev->link_policy = get_unaligned_le16(sent);
184
Johan Hedberg23bb5762010-12-21 23:01:27 +0200185 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200186}
187
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200188static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
189{
190 __u8 status = *((__u8 *) skb->data);
191
192 BT_DBG("%s status 0x%x", hdev->name, status);
193
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300194 clear_bit(HCI_RESET, &hdev->flags);
195
Johan Hedberg23bb5762010-12-21 23:01:27 +0200196 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300197
Johan Hedberg7005ff1782012-01-18 16:14:43 +0200198 /* Reset all flags, except persistent ones */
199 hdev->dev_flags &= BIT(HCI_MGMT) | BIT(HCI_SETUP) | BIT(HCI_AUTO_OFF);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200200}
201
202static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
203{
204 __u8 status = *((__u8 *) skb->data);
205 void *sent;
206
207 BT_DBG("%s status 0x%x", hdev->name, status);
208
209 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
210 if (!sent)
211 return;
212
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200213 hci_dev_lock(hdev);
214
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200215 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200216 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 if (status == 0)
219 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200220
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200221 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200222}
223
224static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
225{
226 struct hci_rp_read_local_name *rp = (void *) skb->data;
227
228 BT_DBG("%s status 0x%x", hdev->name, rp->status);
229
230 if (rp->status)
231 return;
232
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200233 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200234}
235
236static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
237{
238 __u8 status = *((__u8 *) skb->data);
239 void *sent;
240
241 BT_DBG("%s status 0x%x", hdev->name, status);
242
243 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
244 if (!sent)
245 return;
246
247 if (!status) {
248 __u8 param = *((__u8 *) sent);
249
250 if (param == AUTH_ENABLED)
251 set_bit(HCI_AUTH, &hdev->flags);
252 else
253 clear_bit(HCI_AUTH, &hdev->flags);
254 }
255
Johan Hedberg23bb5762010-12-21 23:01:27 +0200256 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200257}
258
259static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
260{
261 __u8 status = *((__u8 *) skb->data);
262 void *sent;
263
264 BT_DBG("%s status 0x%x", hdev->name, status);
265
266 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
267 if (!sent)
268 return;
269
270 if (!status) {
271 __u8 param = *((__u8 *) sent);
272
273 if (param)
274 set_bit(HCI_ENCRYPT, &hdev->flags);
275 else
276 clear_bit(HCI_ENCRYPT, &hdev->flags);
277 }
278
Johan Hedberg23bb5762010-12-21 23:01:27 +0200279 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200280}
281
282static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
283{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200284 __u8 param, status = *((__u8 *) skb->data);
285 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200286 void *sent;
287
288 BT_DBG("%s status 0x%x", hdev->name, status);
289
290 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
291 if (!sent)
292 return;
293
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200294 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200295
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200296 hci_dev_lock(hdev);
297
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200298 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200299 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200300 hdev->discov_timeout = 0;
301 goto done;
302 }
303
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200304 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
305 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200306
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200307 if (param & SCAN_INQUIRY) {
308 set_bit(HCI_ISCAN, &hdev->flags);
309 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200310 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200311 if (hdev->discov_timeout > 0) {
312 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
313 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
314 to);
315 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200316 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200317 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200318
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200319 if (param & SCAN_PAGE) {
320 set_bit(HCI_PSCAN, &hdev->flags);
321 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200322 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200324 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200325
326done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200327 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200328 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200329}
330
331static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
332{
333 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
334
335 BT_DBG("%s status 0x%x", hdev->name, rp->status);
336
337 if (rp->status)
338 return;
339
340 memcpy(hdev->dev_class, rp->dev_class, 3);
341
342 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
343 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
344}
345
346static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
347{
348 __u8 status = *((__u8 *) skb->data);
349 void *sent;
350
351 BT_DBG("%s status 0x%x", hdev->name, status);
352
Marcel Holtmannf383f272008-07-14 20:13:47 +0200353 if (status)
354 return;
355
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200356 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
357 if (!sent)
358 return;
359
Marcel Holtmannf383f272008-07-14 20:13:47 +0200360 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200361}
362
363static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
364{
365 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200367
368 BT_DBG("%s status 0x%x", hdev->name, rp->status);
369
370 if (rp->status)
371 return;
372
373 setting = __le16_to_cpu(rp->voice_setting);
374
Marcel Holtmannf383f272008-07-14 20:13:47 +0200375 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200376 return;
377
378 hdev->voice_setting = setting;
379
380 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
381
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200382 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200383 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384}
385
386static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
387{
388 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200389 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 void *sent;
391
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393
Marcel Holtmannf383f272008-07-14 20:13:47 +0200394 if (status)
395 return;
396
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200397 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
398 if (!sent)
399 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
Marcel Holtmannf383f272008-07-14 20:13:47 +0200401 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Marcel Holtmannf383f272008-07-14 20:13:47 +0200403 if (hdev->voice_setting == setting)
404 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405
Marcel Holtmannf383f272008-07-14 20:13:47 +0200406 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
409
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200410 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200411 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412}
413
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200414static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200416 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200418 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
Johan Hedberg23bb5762010-12-21 23:01:27 +0200420 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421}
422
Marcel Holtmann333140b2008-07-14 20:13:48 +0200423static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
424{
425 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
426
427 BT_DBG("%s status 0x%x", hdev->name, rp->status);
428
429 if (rp->status)
430 return;
431
Johan Hedberg84bde9d2012-01-25 14:21:06 +0200432 if (rp->mode)
433 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
434 else
435 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200436}
437
438static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
439{
440 __u8 status = *((__u8 *) skb->data);
441 void *sent;
442
443 BT_DBG("%s status 0x%x", hdev->name, status);
444
445 if (status)
446 return;
447
448 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
449 if (!sent)
450 return;
451
Johan Hedberg84bde9d2012-01-25 14:21:06 +0200452 if (*((u8 *) sent))
453 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
454 else
455 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200456}
457
Johan Hedbergd5859e22011-01-25 01:19:58 +0200458static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
459{
460 if (hdev->features[6] & LMP_EXT_INQ)
461 return 2;
462
463 if (hdev->features[3] & LMP_RSSI_INQ)
464 return 1;
465
466 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
467 hdev->lmp_subver == 0x0757)
468 return 1;
469
470 if (hdev->manufacturer == 15) {
471 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
472 return 1;
473 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
474 return 1;
475 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
476 return 1;
477 }
478
479 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
480 hdev->lmp_subver == 0x1805)
481 return 1;
482
483 return 0;
484}
485
486static void hci_setup_inquiry_mode(struct hci_dev *hdev)
487{
488 u8 mode;
489
490 mode = hci_get_inquiry_mode(hdev);
491
492 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
493}
494
495static void hci_setup_event_mask(struct hci_dev *hdev)
496{
497 /* The second byte is 0xff instead of 0x9f (two reserved bits
498 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
499 * command otherwise */
500 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
501
Ville Tervo6de6c182011-05-27 11:16:21 +0300502 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
503 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200504 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300505 return;
506
507 events[4] |= 0x01; /* Flow Specification Complete */
508 events[4] |= 0x02; /* Inquiry Result with RSSI */
509 events[4] |= 0x04; /* Read Remote Extended Features Complete */
510 events[5] |= 0x08; /* Synchronous Connection Complete */
511 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200512
513 if (hdev->features[3] & LMP_RSSI_INQ)
514 events[4] |= 0x04; /* Inquiry Result with RSSI */
515
516 if (hdev->features[5] & LMP_SNIFF_SUBR)
517 events[5] |= 0x20; /* Sniff Subrating */
518
519 if (hdev->features[5] & LMP_PAUSE_ENC)
520 events[5] |= 0x80; /* Encryption Key Refresh Complete */
521
522 if (hdev->features[6] & LMP_EXT_INQ)
523 events[5] |= 0x40; /* Extended Inquiry Result */
524
525 if (hdev->features[6] & LMP_NO_FLUSH)
526 events[7] |= 0x01; /* Enhanced Flush Complete */
527
528 if (hdev->features[7] & LMP_LSTO)
529 events[6] |= 0x80; /* Link Supervision Timeout Changed */
530
531 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
532 events[6] |= 0x01; /* IO Capability Request */
533 events[6] |= 0x02; /* IO Capability Response */
534 events[6] |= 0x04; /* User Confirmation Request */
535 events[6] |= 0x08; /* User Passkey Request */
536 events[6] |= 0x10; /* Remote OOB Data Request */
537 events[6] |= 0x20; /* Simple Pairing Complete */
538 events[7] |= 0x04; /* User Passkey Notification */
539 events[7] |= 0x08; /* Keypress Notification */
540 events[7] |= 0x10; /* Remote Host Supported
541 * Features Notification */
542 }
543
544 if (hdev->features[4] & LMP_LE)
545 events[7] |= 0x20; /* LE Meta-Event */
546
547 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
548}
549
Andre Guedese6100a22011-06-30 19:20:54 -0300550static void hci_set_le_support(struct hci_dev *hdev)
551{
552 struct hci_cp_write_le_host_supported cp;
553
554 memset(&cp, 0, sizeof(cp));
555
556 if (enable_le) {
557 cp.le = 1;
558 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
559 }
560
561 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
562}
563
Johan Hedbergd5859e22011-01-25 01:19:58 +0200564static void hci_setup(struct hci_dev *hdev)
565{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200566 if (hdev->dev_type != HCI_BREDR)
567 return;
568
Johan Hedbergd5859e22011-01-25 01:19:58 +0200569 hci_setup_event_mask(hdev);
570
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200571 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200572 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
573
574 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
575 u8 mode = 0x01;
576 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
577 }
578
579 if (hdev->features[3] & LMP_RSSI_INQ)
580 hci_setup_inquiry_mode(hdev);
581
582 if (hdev->features[7] & LMP_INQ_TX_PWR)
583 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300584
585 if (hdev->features[7] & LMP_EXTFEATURES) {
586 struct hci_cp_read_local_ext_features cp;
587
588 cp.page = 0x01;
589 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
590 sizeof(cp), &cp);
591 }
Andre Guedese6100a22011-06-30 19:20:54 -0300592
593 if (hdev->features[4] & LMP_LE)
594 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200595}
596
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200597static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
598{
599 struct hci_rp_read_local_version *rp = (void *) skb->data;
600
601 BT_DBG("%s status 0x%x", hdev->name, rp->status);
602
603 if (rp->status)
604 return;
605
606 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200607 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200608 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200609 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200610 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200611
612 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
613 hdev->manufacturer,
614 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200615
616 if (test_bit(HCI_INIT, &hdev->flags))
617 hci_setup(hdev);
618}
619
620static void hci_setup_link_policy(struct hci_dev *hdev)
621{
622 u16 link_policy = 0;
623
624 if (hdev->features[0] & LMP_RSWITCH)
625 link_policy |= HCI_LP_RSWITCH;
626 if (hdev->features[0] & LMP_HOLD)
627 link_policy |= HCI_LP_HOLD;
628 if (hdev->features[0] & LMP_SNIFF)
629 link_policy |= HCI_LP_SNIFF;
630 if (hdev->features[1] & LMP_PARK)
631 link_policy |= HCI_LP_PARK;
632
633 link_policy = cpu_to_le16(link_policy);
634 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
635 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200636}
637
638static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
639{
640 struct hci_rp_read_local_commands *rp = (void *) skb->data;
641
642 BT_DBG("%s status 0x%x", hdev->name, rp->status);
643
644 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200645 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200646
647 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200648
649 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
650 hci_setup_link_policy(hdev);
651
652done:
653 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200654}
655
656static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
657{
658 struct hci_rp_read_local_features *rp = (void *) skb->data;
659
660 BT_DBG("%s status 0x%x", hdev->name, rp->status);
661
662 if (rp->status)
663 return;
664
665 memcpy(hdev->features, rp->features, 8);
666
667 /* Adjust default settings according to features
668 * supported by device. */
669
670 if (hdev->features[0] & LMP_3SLOT)
671 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
672
673 if (hdev->features[0] & LMP_5SLOT)
674 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
675
676 if (hdev->features[1] & LMP_HV2) {
677 hdev->pkt_type |= (HCI_HV2);
678 hdev->esco_type |= (ESCO_HV2);
679 }
680
681 if (hdev->features[1] & LMP_HV3) {
682 hdev->pkt_type |= (HCI_HV3);
683 hdev->esco_type |= (ESCO_HV3);
684 }
685
686 if (hdev->features[3] & LMP_ESCO)
687 hdev->esco_type |= (ESCO_EV3);
688
689 if (hdev->features[4] & LMP_EV4)
690 hdev->esco_type |= (ESCO_EV4);
691
692 if (hdev->features[4] & LMP_EV5)
693 hdev->esco_type |= (ESCO_EV5);
694
Marcel Holtmannefc76882009-02-06 09:13:37 +0100695 if (hdev->features[5] & LMP_EDR_ESCO_2M)
696 hdev->esco_type |= (ESCO_2EV3);
697
698 if (hdev->features[5] & LMP_EDR_ESCO_3M)
699 hdev->esco_type |= (ESCO_3EV3);
700
701 if (hdev->features[5] & LMP_EDR_3S_ESCO)
702 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
703
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200704 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
705 hdev->features[0], hdev->features[1],
706 hdev->features[2], hdev->features[3],
707 hdev->features[4], hdev->features[5],
708 hdev->features[6], hdev->features[7]);
709}
710
Andre Guedes971e3a42011-06-30 19:20:52 -0300711static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
712 struct sk_buff *skb)
713{
714 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
715
716 BT_DBG("%s status 0x%x", hdev->name, rp->status);
717
718 if (rp->status)
719 return;
720
Andre Guedesb5b32b62011-12-30 10:34:04 -0300721 switch (rp->page) {
722 case 0:
723 memcpy(hdev->features, rp->features, 8);
724 break;
725 case 1:
726 memcpy(hdev->host_features, rp->features, 8);
727 break;
728 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300729
730 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
731}
732
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200733static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
734 struct sk_buff *skb)
735{
736 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
737
738 BT_DBG("%s status 0x%x", hdev->name, rp->status);
739
740 if (rp->status)
741 return;
742
743 hdev->flow_ctl_mode = rp->mode;
744
745 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
746}
747
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200748static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
749{
750 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
751
752 BT_DBG("%s status 0x%x", hdev->name, rp->status);
753
754 if (rp->status)
755 return;
756
757 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
758 hdev->sco_mtu = rp->sco_mtu;
759 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
760 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
761
762 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
763 hdev->sco_mtu = 64;
764 hdev->sco_pkts = 8;
765 }
766
767 hdev->acl_cnt = hdev->acl_pkts;
768 hdev->sco_cnt = hdev->sco_pkts;
769
770 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
771 hdev->acl_mtu, hdev->acl_pkts,
772 hdev->sco_mtu, hdev->sco_pkts);
773}
774
775static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
776{
777 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
778
779 BT_DBG("%s status 0x%x", hdev->name, rp->status);
780
781 if (!rp->status)
782 bacpy(&hdev->bdaddr, &rp->bdaddr);
783
Johan Hedberg23bb5762010-12-21 23:01:27 +0200784 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
785}
786
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200787static void hci_cc_read_data_block_size(struct hci_dev *hdev,
788 struct sk_buff *skb)
789{
790 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
791
792 BT_DBG("%s status 0x%x", hdev->name, rp->status);
793
794 if (rp->status)
795 return;
796
797 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
798 hdev->block_len = __le16_to_cpu(rp->block_len);
799 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
800
801 hdev->block_cnt = hdev->num_blocks;
802
803 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
804 hdev->block_cnt, hdev->block_len);
805
806 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
807}
808
Johan Hedberg23bb5762010-12-21 23:01:27 +0200809static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
810{
811 __u8 status = *((__u8 *) skb->data);
812
813 BT_DBG("%s status 0x%x", hdev->name, status);
814
815 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200816}
817
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300818static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
819 struct sk_buff *skb)
820{
821 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
822
823 BT_DBG("%s status 0x%x", hdev->name, rp->status);
824
825 if (rp->status)
826 return;
827
828 hdev->amp_status = rp->amp_status;
829 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
830 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
831 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
832 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
833 hdev->amp_type = rp->amp_type;
834 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
835 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
836 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
837 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
838
839 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
840}
841
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200842static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
843 struct sk_buff *skb)
844{
845 __u8 status = *((__u8 *) skb->data);
846
847 BT_DBG("%s status 0x%x", hdev->name, status);
848
849 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
850}
851
Johan Hedbergd5859e22011-01-25 01:19:58 +0200852static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
853{
854 __u8 status = *((__u8 *) skb->data);
855
856 BT_DBG("%s status 0x%x", hdev->name, status);
857
858 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
859}
860
861static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
862 struct sk_buff *skb)
863{
864 __u8 status = *((__u8 *) skb->data);
865
866 BT_DBG("%s status 0x%x", hdev->name, status);
867
868 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
869}
870
871static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
872 struct sk_buff *skb)
873{
874 __u8 status = *((__u8 *) skb->data);
875
876 BT_DBG("%s status 0x%x", hdev->name, status);
877
878 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
879}
880
881static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
882{
883 __u8 status = *((__u8 *) skb->data);
884
885 BT_DBG("%s status 0x%x", hdev->name, status);
886
887 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
888}
889
Johan Hedberg980e1a52011-01-22 06:10:07 +0200890static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
891{
892 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
893 struct hci_cp_pin_code_reply *cp;
894 struct hci_conn *conn;
895
896 BT_DBG("%s status 0x%x", hdev->name, rp->status);
897
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200898 hci_dev_lock(hdev);
899
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200900 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200901 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200902
903 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200904 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200905
906 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
907 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200908 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200909
910 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
911 if (conn)
912 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200913
914unlock:
915 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200916}
917
918static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
919{
920 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
921
922 BT_DBG("%s status 0x%x", hdev->name, rp->status);
923
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200924 hci_dev_lock(hdev);
925
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200926 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200927 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200928 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200929
930 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200931}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200932
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300933static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
934 struct sk_buff *skb)
935{
936 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
937
938 BT_DBG("%s status 0x%x", hdev->name, rp->status);
939
940 if (rp->status)
941 return;
942
943 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
944 hdev->le_pkts = rp->le_max_pkt;
945
946 hdev->le_cnt = hdev->le_pkts;
947
948 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
949
950 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
951}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200952
Johan Hedberga5c29682011-02-19 12:05:57 -0300953static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
954{
955 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
956
957 BT_DBG("%s status 0x%x", hdev->name, rp->status);
958
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200959 hci_dev_lock(hdev);
960
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200961 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200962 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300963 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200964
965 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300966}
967
968static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
969 struct sk_buff *skb)
970{
971 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
972
973 BT_DBG("%s status 0x%x", hdev->name, rp->status);
974
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200975 hci_dev_lock(hdev);
976
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200977 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200978 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300979 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200980
981 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300982}
983
Brian Gix1143d452011-11-23 08:28:34 -0800984static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
985{
986 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
987
988 BT_DBG("%s status 0x%x", hdev->name, rp->status);
989
990 hci_dev_lock(hdev);
991
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200992 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800993 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr,
994 rp->status);
995
996 hci_dev_unlock(hdev);
997}
998
999static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1000 struct sk_buff *skb)
1001{
1002 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1003
1004 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1005
1006 hci_dev_lock(hdev);
1007
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001008 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001009 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
1010 rp->status);
1011
1012 hci_dev_unlock(hdev);
1013}
1014
Szymon Jancc35938b2011-03-22 13:12:21 +01001015static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1016 struct sk_buff *skb)
1017{
1018 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1019
1020 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1021
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001022 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001023 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001024 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001025 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001026}
1027
Andre Guedes07f7fa52011-12-02 21:13:31 +09001028static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1029{
1030 __u8 status = *((__u8 *) skb->data);
1031
1032 BT_DBG("%s status 0x%x", hdev->name, status);
1033}
1034
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001035static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1036 struct sk_buff *skb)
1037{
1038 struct hci_cp_le_set_scan_enable *cp;
1039 __u8 status = *((__u8 *) skb->data);
1040
1041 BT_DBG("%s status 0x%x", hdev->name, status);
1042
1043 if (status)
1044 return;
1045
1046 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1047 if (!cp)
1048 return;
1049
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001050 switch (cp->enable) {
1051 case LE_SCANNING_ENABLED:
Andre Guedesd23264a2011-11-25 20:53:38 -03001052 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1053
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001054 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001055
1056 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001057 hci_adv_entries_clear(hdev);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001058 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001059 break;
1060
1061 case LE_SCANNING_DISABLED:
Andre Guedesd23264a2011-11-25 20:53:38 -03001062 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1063
Andre Guedesd0843292012-01-02 19:18:11 -03001064 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001065 break;
1066
1067 default:
1068 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1069 break;
Andre Guedes35815082011-05-26 16:23:53 -03001070 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001071}
1072
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001073static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1074{
1075 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1076
1077 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1078
1079 if (rp->status)
1080 return;
1081
1082 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1083}
1084
1085static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1086{
1087 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1088
1089 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1090
1091 if (rp->status)
1092 return;
1093
1094 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1095}
1096
Andre Guedesf9b49302011-06-30 19:20:53 -03001097static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1098 struct sk_buff *skb)
1099{
1100 struct hci_cp_read_local_ext_features cp;
1101 __u8 status = *((__u8 *) skb->data);
1102
1103 BT_DBG("%s status 0x%x", hdev->name, status);
1104
1105 if (status)
1106 return;
1107
1108 cp.page = 0x01;
1109 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1110}
1111
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001112static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1113{
1114 BT_DBG("%s status 0x%x", hdev->name, status);
1115
1116 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001117 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001118 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001119 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001120 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001121 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001122 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001123 return;
1124 }
1125
Andre Guedes89352e72011-11-04 14:16:53 -03001126 set_bit(HCI_INQUIRY, &hdev->flags);
1127
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001128 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001129 hci_discovery_set_state(hdev, DISCOVERY_INQUIRY);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001130 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001131}
1132
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1134{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001135 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001138 BT_DBG("%s status 0x%x", hdev->name, status);
1139
1140 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 if (!cp)
1142 return;
1143
1144 hci_dev_lock(hdev);
1145
1146 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1147
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001148 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149
1150 if (status) {
1151 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001152 if (status != 0x0c || conn->attempt > 2) {
1153 conn->state = BT_CLOSED;
1154 hci_proto_connect_cfm(conn, status);
1155 hci_conn_del(conn);
1156 } else
1157 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 }
1159 } else {
1160 if (!conn) {
1161 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1162 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001163 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 conn->link_mode |= HCI_LM_MASTER;
1165 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001166 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167 }
1168 }
1169
1170 hci_dev_unlock(hdev);
1171}
1172
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001173static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001175 struct hci_cp_add_sco *cp;
1176 struct hci_conn *acl, *sco;
1177 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001179 BT_DBG("%s status 0x%x", hdev->name, status);
1180
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001181 if (!status)
1182 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001184 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1185 if (!cp)
1186 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001188 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001190 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001191
1192 hci_dev_lock(hdev);
1193
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001194 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001195 if (acl) {
1196 sco = acl->link;
1197 if (sco) {
1198 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001199
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001200 hci_proto_connect_cfm(sco, status);
1201 hci_conn_del(sco);
1202 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001203 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001204
1205 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206}
1207
Marcel Holtmannf8558552008-07-14 20:13:49 +02001208static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1209{
1210 struct hci_cp_auth_requested *cp;
1211 struct hci_conn *conn;
1212
1213 BT_DBG("%s status 0x%x", hdev->name, status);
1214
1215 if (!status)
1216 return;
1217
1218 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1219 if (!cp)
1220 return;
1221
1222 hci_dev_lock(hdev);
1223
1224 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1225 if (conn) {
1226 if (conn->state == BT_CONFIG) {
1227 hci_proto_connect_cfm(conn, status);
1228 hci_conn_put(conn);
1229 }
1230 }
1231
1232 hci_dev_unlock(hdev);
1233}
1234
1235static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1236{
1237 struct hci_cp_set_conn_encrypt *cp;
1238 struct hci_conn *conn;
1239
1240 BT_DBG("%s status 0x%x", hdev->name, status);
1241
1242 if (!status)
1243 return;
1244
1245 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1246 if (!cp)
1247 return;
1248
1249 hci_dev_lock(hdev);
1250
1251 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1252 if (conn) {
1253 if (conn->state == BT_CONFIG) {
1254 hci_proto_connect_cfm(conn, status);
1255 hci_conn_put(conn);
1256 }
1257 }
1258
1259 hci_dev_unlock(hdev);
1260}
1261
Johan Hedberg127178d2010-11-18 22:22:29 +02001262static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001263 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001264{
Johan Hedberg392599b2010-11-18 22:22:28 +02001265 if (conn->state != BT_CONFIG || !conn->out)
1266 return 0;
1267
Johan Hedberg765c2a92011-01-19 12:06:52 +05301268 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001269 return 0;
1270
1271 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001272 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedberg84bde9d2012-01-25 14:21:06 +02001273 if (!(test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
Johan Hedberg58a681e2012-01-16 06:47:28 +02001274 test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001275 conn->pending_sec_level != BT_SECURITY_HIGH &&
1276 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001277 return 0;
1278
Johan Hedberg392599b2010-11-18 22:22:28 +02001279 return 1;
1280}
1281
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001282static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1283{
1284 struct hci_cp_remote_name_req cp;
1285
1286 memset(&cp, 0, sizeof(cp));
1287
1288 bacpy(&cp.bdaddr, &e->data.bdaddr);
1289 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1290 cp.pscan_mode = e->data.pscan_mode;
1291 cp.clock_offset = e->data.clock_offset;
1292
1293 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1294}
1295
Johan Hedbergb644ba32012-01-17 21:48:47 +02001296static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001297{
1298 struct discovery_state *discov = &hdev->discovery;
1299 struct inquiry_entry *e;
1300
Johan Hedbergb644ba32012-01-17 21:48:47 +02001301 if (list_empty(&discov->resolve))
1302 return false;
1303
1304 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1305 if (hci_resolve_name(hdev, e) == 0) {
1306 e->name_state = NAME_PENDING;
1307 return true;
1308 }
1309
1310 return false;
1311}
1312
1313static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1314 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1315{
1316 struct discovery_state *discov = &hdev->discovery;
1317 struct inquiry_entry *e;
1318
1319 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1320 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
1321 name, name_len, conn->dev_class);
1322
1323 if (discov->state == DISCOVERY_STOPPED)
1324 return;
1325
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001326 if (discov->state == DISCOVERY_STOPPING)
1327 goto discov_complete;
1328
1329 if (discov->state != DISCOVERY_RESOLVING)
1330 return;
1331
1332 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1333 if (e) {
1334 e->name_state = NAME_KNOWN;
1335 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001336 if (name)
1337 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1338 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001339 }
1340
Johan Hedbergb644ba32012-01-17 21:48:47 +02001341 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001342 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001343
1344discov_complete:
1345 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1346}
1347
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001348static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1349{
Johan Hedberg127178d2010-11-18 22:22:29 +02001350 struct hci_cp_remote_name_req *cp;
1351 struct hci_conn *conn;
1352
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001353 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001354
1355 /* If successful wait for the name req complete event before
1356 * checking for the need to do authentication */
1357 if (!status)
1358 return;
1359
1360 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1361 if (!cp)
1362 return;
1363
1364 hci_dev_lock(hdev);
1365
1366 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001367
1368 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1369 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1370
Johan Hedberg79c6c702011-04-28 11:28:55 -07001371 if (!conn)
1372 goto unlock;
1373
1374 if (!hci_outgoing_auth_needed(hdev, conn))
1375 goto unlock;
1376
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001377 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001378 struct hci_cp_auth_requested cp;
1379 cp.handle = __cpu_to_le16(conn->handle);
1380 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1381 }
1382
Johan Hedberg79c6c702011-04-28 11:28:55 -07001383unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001384 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001385}
1386
Marcel Holtmann769be972008-07-14 20:13:49 +02001387static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1388{
1389 struct hci_cp_read_remote_features *cp;
1390 struct hci_conn *conn;
1391
1392 BT_DBG("%s status 0x%x", hdev->name, status);
1393
1394 if (!status)
1395 return;
1396
1397 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1398 if (!cp)
1399 return;
1400
1401 hci_dev_lock(hdev);
1402
1403 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1404 if (conn) {
1405 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001406 hci_proto_connect_cfm(conn, status);
1407 hci_conn_put(conn);
1408 }
1409 }
1410
1411 hci_dev_unlock(hdev);
1412}
1413
1414static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1415{
1416 struct hci_cp_read_remote_ext_features *cp;
1417 struct hci_conn *conn;
1418
1419 BT_DBG("%s status 0x%x", hdev->name, status);
1420
1421 if (!status)
1422 return;
1423
1424 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1425 if (!cp)
1426 return;
1427
1428 hci_dev_lock(hdev);
1429
1430 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1431 if (conn) {
1432 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001433 hci_proto_connect_cfm(conn, status);
1434 hci_conn_put(conn);
1435 }
1436 }
1437
1438 hci_dev_unlock(hdev);
1439}
1440
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001441static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1442{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001443 struct hci_cp_setup_sync_conn *cp;
1444 struct hci_conn *acl, *sco;
1445 __u16 handle;
1446
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001447 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001448
1449 if (!status)
1450 return;
1451
1452 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1453 if (!cp)
1454 return;
1455
1456 handle = __le16_to_cpu(cp->handle);
1457
1458 BT_DBG("%s handle %d", hdev->name, handle);
1459
1460 hci_dev_lock(hdev);
1461
1462 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001463 if (acl) {
1464 sco = acl->link;
1465 if (sco) {
1466 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001467
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001468 hci_proto_connect_cfm(sco, status);
1469 hci_conn_del(sco);
1470 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001471 }
1472
1473 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001474}
1475
1476static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1477{
1478 struct hci_cp_sniff_mode *cp;
1479 struct hci_conn *conn;
1480
1481 BT_DBG("%s status 0x%x", hdev->name, status);
1482
1483 if (!status)
1484 return;
1485
1486 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1487 if (!cp)
1488 return;
1489
1490 hci_dev_lock(hdev);
1491
1492 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001493 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001494 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001495
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001496 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001497 hci_sco_setup(conn, status);
1498 }
1499
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001500 hci_dev_unlock(hdev);
1501}
1502
1503static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1504{
1505 struct hci_cp_exit_sniff_mode *cp;
1506 struct hci_conn *conn;
1507
1508 BT_DBG("%s status 0x%x", hdev->name, status);
1509
1510 if (!status)
1511 return;
1512
1513 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1514 if (!cp)
1515 return;
1516
1517 hci_dev_lock(hdev);
1518
1519 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001520 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001521 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001522
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001523 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001524 hci_sco_setup(conn, status);
1525 }
1526
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001527 hci_dev_unlock(hdev);
1528}
1529
Ville Tervofcd89c02011-02-10 22:38:47 -03001530static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1531{
1532 struct hci_cp_le_create_conn *cp;
1533 struct hci_conn *conn;
1534
1535 BT_DBG("%s status 0x%x", hdev->name, status);
1536
1537 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1538 if (!cp)
1539 return;
1540
1541 hci_dev_lock(hdev);
1542
1543 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1544
1545 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1546 conn);
1547
1548 if (status) {
1549 if (conn && conn->state == BT_CONNECT) {
1550 conn->state = BT_CLOSED;
1551 hci_proto_connect_cfm(conn, status);
1552 hci_conn_del(conn);
1553 }
1554 } else {
1555 if (!conn) {
1556 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001557 if (conn) {
1558 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001559 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001560 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001561 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001562 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001563 }
1564 }
1565
1566 hci_dev_unlock(hdev);
1567}
1568
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001569static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1570{
1571 BT_DBG("%s status 0x%x", hdev->name, status);
1572}
1573
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001574static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1575{
1576 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001577 struct discovery_state *discov = &hdev->discovery;
1578 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001579
1580 BT_DBG("%s status %d", hdev->name, status);
1581
Johan Hedberg23bb5762010-12-21 23:01:27 +02001582 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001583
1584 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001585
1586 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1587 return;
1588
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001589 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001590 return;
1591
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001592 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001593
1594 if (discov->state != DISCOVERY_INQUIRY)
1595 goto unlock;
1596
1597 if (list_empty(&discov->resolve)) {
1598 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1599 goto unlock;
1600 }
1601
1602 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1603 if (e && hci_resolve_name(hdev, e) == 0) {
1604 e->name_state = NAME_PENDING;
1605 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1606 } else {
1607 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1608 }
1609
1610unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001611 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001612}
1613
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1615{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001616 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001617 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 int num_rsp = *((__u8 *) skb->data);
1619
1620 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1621
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001622 if (!num_rsp)
1623 return;
1624
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001626
Johan Hedberge17acd42011-03-30 23:57:16 +03001627 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg31754052012-01-04 13:39:52 +02001628 bool name_known;
1629
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 bacpy(&data.bdaddr, &info->bdaddr);
1631 data.pscan_rep_mode = info->pscan_rep_mode;
1632 data.pscan_period_mode = info->pscan_period_mode;
1633 data.pscan_mode = info->pscan_mode;
1634 memcpy(data.dev_class, info->dev_class, 3);
1635 data.clock_offset = info->clock_offset;
1636 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001637 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001638
1639 name_known = hci_inquiry_cache_update(hdev, &data, false);
Johan Hedberg48264f02011-11-09 13:58:58 +02001640 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Andre Guedes7d262f82012-01-10 18:20:49 -03001641 info->dev_class, 0, !name_known,
1642 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001644
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645 hci_dev_unlock(hdev);
1646}
1647
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001648static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001650 struct hci_ev_conn_complete *ev = (void *) skb->data;
1651 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001653 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001654
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001656
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001657 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001658 if (!conn) {
1659 if (ev->link_type != SCO_LINK)
1660 goto unlock;
1661
1662 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1663 if (!conn)
1664 goto unlock;
1665
1666 conn->type = SCO_LINK;
1667 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001668
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001669 if (!ev->status) {
1670 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001671
1672 if (conn->type == ACL_LINK) {
1673 conn->state = BT_CONFIG;
1674 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001675 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001676 } else
1677 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001678
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001679 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001680 hci_conn_add_sysfs(conn);
1681
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001682 if (test_bit(HCI_AUTH, &hdev->flags))
1683 conn->link_mode |= HCI_LM_AUTH;
1684
1685 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1686 conn->link_mode |= HCI_LM_ENCRYPT;
1687
1688 /* Get remote features */
1689 if (conn->type == ACL_LINK) {
1690 struct hci_cp_read_remote_features cp;
1691 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001692 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1693 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001694 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001695
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001696 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001697 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001698 struct hci_cp_change_conn_ptype cp;
1699 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001700 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1701 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1702 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001703 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001704 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001705 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001706 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001707 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001708 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001709 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001710
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001711 if (conn->type == ACL_LINK)
1712 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001713
Marcel Holtmann769be972008-07-14 20:13:49 +02001714 if (ev->status) {
1715 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001716 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001717 } else if (ev->link_type != ACL_LINK)
1718 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001719
1720unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001722
1723 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724}
1725
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1727{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001728 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 int mask = hdev->link_mode;
1730
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001731 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1732 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733
1734 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1735
Szymon Janc138d22e2011-02-17 16:44:23 +01001736 if ((mask & HCI_LM_ACCEPT) &&
1737 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001739 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741
1742 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001743
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001744 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1745 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001746 memcpy(ie->data.dev_class, ev->dev_class, 3);
1747
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1749 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001750 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1751 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001752 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 hci_dev_unlock(hdev);
1754 return;
1755 }
1756 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001757
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758 memcpy(conn->dev_class, ev->dev_class, 3);
1759 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001760
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 hci_dev_unlock(hdev);
1762
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001763 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1764 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001766 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001768 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1769 cp.role = 0x00; /* Become master */
1770 else
1771 cp.role = 0x01; /* Remain slave */
1772
1773 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1774 sizeof(cp), &cp);
1775 } else {
1776 struct hci_cp_accept_sync_conn_req cp;
1777
1778 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001779 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001780
1781 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1782 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1783 cp.max_latency = cpu_to_le16(0xffff);
1784 cp.content_format = cpu_to_le16(hdev->voice_setting);
1785 cp.retrans_effort = 0xff;
1786
1787 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1788 sizeof(cp), &cp);
1789 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 } else {
1791 /* Connection rejected */
1792 struct hci_cp_reject_conn_req cp;
1793
1794 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001795 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001796 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 }
1798}
1799
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1801{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001802 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001803 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804
1805 BT_DBG("%s status %d", hdev->name, ev->status);
1806
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 hci_dev_lock(hdev);
1808
Marcel Holtmann04837f62006-07-03 10:02:33 +02001809 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001810 if (!conn)
1811 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001812
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001813 if (ev->status == 0)
1814 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815
Johan Hedbergb644ba32012-01-17 21:48:47 +02001816 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1817 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001818 if (ev->status != 0)
1819 mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
1820 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001821 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001822 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001823 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001824
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001825 if (ev->status == 0) {
1826 hci_proto_disconn_cfm(conn, ev->reason);
1827 hci_conn_del(conn);
1828 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001829
1830unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 hci_dev_unlock(hdev);
1832}
1833
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001834static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1835{
1836 struct hci_ev_auth_complete *ev = (void *) skb->data;
1837 struct hci_conn *conn;
1838
1839 BT_DBG("%s status %d", hdev->name, ev->status);
1840
1841 hci_dev_lock(hdev);
1842
1843 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001844 if (!conn)
1845 goto unlock;
1846
1847 if (!ev->status) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02001848 if (!(test_bit(HCI_CONN_SSP_ENABLED, &conn->flags) &&
Johan Hedberg84bde9d2012-01-25 14:21:06 +02001849 test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) &&
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001850 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001851 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001852 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001853 conn->link_mode |= HCI_LM_AUTH;
1854 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001855 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001856 } else {
Johan Hedberg744cf192011-11-08 20:40:14 +02001857 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001858 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001859
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001860 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1861 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001862
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001863 if (conn->state == BT_CONFIG) {
Johan Hedberg84bde9d2012-01-25 14:21:06 +02001864 if (!ev->status &&
1865 test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
Johan Hedberg58a681e2012-01-16 06:47:28 +02001866 test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001867 struct hci_cp_set_conn_encrypt cp;
1868 cp.handle = ev->handle;
1869 cp.encrypt = 0x01;
1870 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1871 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001872 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001873 conn->state = BT_CONNECTED;
1874 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001875 hci_conn_put(conn);
1876 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001877 } else {
1878 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001879
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001880 hci_conn_hold(conn);
1881 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1882 hci_conn_put(conn);
1883 }
1884
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001885 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001886 if (!ev->status) {
1887 struct hci_cp_set_conn_encrypt cp;
1888 cp.handle = ev->handle;
1889 cp.encrypt = 0x01;
1890 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1891 &cp);
1892 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001893 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001894 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001895 }
1896 }
1897
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001898unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001899 hci_dev_unlock(hdev);
1900}
1901
1902static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1903{
Johan Hedberg127178d2010-11-18 22:22:29 +02001904 struct hci_ev_remote_name *ev = (void *) skb->data;
1905 struct hci_conn *conn;
1906
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001907 BT_DBG("%s", hdev->name);
1908
1909 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001910
1911 hci_dev_lock(hdev);
1912
1913 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001914
1915 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1916 goto check_auth;
1917
1918 if (ev->status == 0)
1919 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1920 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1921 else
1922 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1923
1924check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001925 if (!conn)
1926 goto unlock;
1927
1928 if (!hci_outgoing_auth_needed(hdev, conn))
1929 goto unlock;
1930
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001931 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001932 struct hci_cp_auth_requested cp;
1933 cp.handle = __cpu_to_le16(conn->handle);
1934 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1935 }
1936
Johan Hedberg79c6c702011-04-28 11:28:55 -07001937unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001938 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001939}
1940
1941static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1942{
1943 struct hci_ev_encrypt_change *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) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001953 if (ev->encrypt) {
1954 /* Encryption implies authentication */
1955 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001956 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001957 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001958 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001959 conn->link_mode &= ~HCI_LM_ENCRYPT;
1960 }
1961
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001962 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001963
Marcel Holtmannf8558552008-07-14 20:13:49 +02001964 if (conn->state == BT_CONFIG) {
1965 if (!ev->status)
1966 conn->state = BT_CONNECTED;
1967
1968 hci_proto_connect_cfm(conn, ev->status);
1969 hci_conn_put(conn);
1970 } else
1971 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001972 }
1973
1974 hci_dev_unlock(hdev);
1975}
1976
1977static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1978{
1979 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1980 struct hci_conn *conn;
1981
1982 BT_DBG("%s status %d", hdev->name, ev->status);
1983
1984 hci_dev_lock(hdev);
1985
1986 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1987 if (conn) {
1988 if (!ev->status)
1989 conn->link_mode |= HCI_LM_SECURE;
1990
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001991 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001992
1993 hci_key_change_cfm(conn, ev->status);
1994 }
1995
1996 hci_dev_unlock(hdev);
1997}
1998
1999static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2000{
2001 struct hci_ev_remote_features *ev = (void *) skb->data;
2002 struct hci_conn *conn;
2003
2004 BT_DBG("%s status %d", hdev->name, ev->status);
2005
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002006 hci_dev_lock(hdev);
2007
2008 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002009 if (!conn)
2010 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002011
Johan Hedbergccd556f2010-11-10 17:11:51 +02002012 if (!ev->status)
2013 memcpy(conn->features, ev->features, 8);
2014
2015 if (conn->state != BT_CONFIG)
2016 goto unlock;
2017
2018 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2019 struct hci_cp_read_remote_ext_features cp;
2020 cp.handle = ev->handle;
2021 cp.page = 0x01;
2022 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002023 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002024 goto unlock;
2025 }
2026
Johan Hedberg127178d2010-11-18 22:22:29 +02002027 if (!ev->status) {
2028 struct hci_cp_remote_name_req cp;
2029 memset(&cp, 0, sizeof(cp));
2030 bacpy(&cp.bdaddr, &conn->dst);
2031 cp.pscan_rep_mode = 0x02;
2032 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002033 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2034 mgmt_device_connected(hdev, &conn->dst, conn->type,
2035 conn->dst_type, NULL, 0,
2036 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002037
Johan Hedberg127178d2010-11-18 22:22:29 +02002038 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002039 conn->state = BT_CONNECTED;
2040 hci_proto_connect_cfm(conn, ev->status);
2041 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002042 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002043
Johan Hedbergccd556f2010-11-10 17:11:51 +02002044unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002045 hci_dev_unlock(hdev);
2046}
2047
2048static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2049{
2050 BT_DBG("%s", hdev->name);
2051}
2052
2053static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2054{
2055 BT_DBG("%s", hdev->name);
2056}
2057
2058static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2059{
2060 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2061 __u16 opcode;
2062
2063 skb_pull(skb, sizeof(*ev));
2064
2065 opcode = __le16_to_cpu(ev->opcode);
2066
2067 switch (opcode) {
2068 case HCI_OP_INQUIRY_CANCEL:
2069 hci_cc_inquiry_cancel(hdev, skb);
2070 break;
2071
2072 case HCI_OP_EXIT_PERIODIC_INQ:
2073 hci_cc_exit_periodic_inq(hdev, skb);
2074 break;
2075
2076 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2077 hci_cc_remote_name_req_cancel(hdev, skb);
2078 break;
2079
2080 case HCI_OP_ROLE_DISCOVERY:
2081 hci_cc_role_discovery(hdev, skb);
2082 break;
2083
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002084 case HCI_OP_READ_LINK_POLICY:
2085 hci_cc_read_link_policy(hdev, skb);
2086 break;
2087
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002088 case HCI_OP_WRITE_LINK_POLICY:
2089 hci_cc_write_link_policy(hdev, skb);
2090 break;
2091
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002092 case HCI_OP_READ_DEF_LINK_POLICY:
2093 hci_cc_read_def_link_policy(hdev, skb);
2094 break;
2095
2096 case HCI_OP_WRITE_DEF_LINK_POLICY:
2097 hci_cc_write_def_link_policy(hdev, skb);
2098 break;
2099
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002100 case HCI_OP_RESET:
2101 hci_cc_reset(hdev, skb);
2102 break;
2103
2104 case HCI_OP_WRITE_LOCAL_NAME:
2105 hci_cc_write_local_name(hdev, skb);
2106 break;
2107
2108 case HCI_OP_READ_LOCAL_NAME:
2109 hci_cc_read_local_name(hdev, skb);
2110 break;
2111
2112 case HCI_OP_WRITE_AUTH_ENABLE:
2113 hci_cc_write_auth_enable(hdev, skb);
2114 break;
2115
2116 case HCI_OP_WRITE_ENCRYPT_MODE:
2117 hci_cc_write_encrypt_mode(hdev, skb);
2118 break;
2119
2120 case HCI_OP_WRITE_SCAN_ENABLE:
2121 hci_cc_write_scan_enable(hdev, skb);
2122 break;
2123
2124 case HCI_OP_READ_CLASS_OF_DEV:
2125 hci_cc_read_class_of_dev(hdev, skb);
2126 break;
2127
2128 case HCI_OP_WRITE_CLASS_OF_DEV:
2129 hci_cc_write_class_of_dev(hdev, skb);
2130 break;
2131
2132 case HCI_OP_READ_VOICE_SETTING:
2133 hci_cc_read_voice_setting(hdev, skb);
2134 break;
2135
2136 case HCI_OP_WRITE_VOICE_SETTING:
2137 hci_cc_write_voice_setting(hdev, skb);
2138 break;
2139
2140 case HCI_OP_HOST_BUFFER_SIZE:
2141 hci_cc_host_buffer_size(hdev, skb);
2142 break;
2143
Marcel Holtmann333140b2008-07-14 20:13:48 +02002144 case HCI_OP_READ_SSP_MODE:
2145 hci_cc_read_ssp_mode(hdev, skb);
2146 break;
2147
2148 case HCI_OP_WRITE_SSP_MODE:
2149 hci_cc_write_ssp_mode(hdev, skb);
2150 break;
2151
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002152 case HCI_OP_READ_LOCAL_VERSION:
2153 hci_cc_read_local_version(hdev, skb);
2154 break;
2155
2156 case HCI_OP_READ_LOCAL_COMMANDS:
2157 hci_cc_read_local_commands(hdev, skb);
2158 break;
2159
2160 case HCI_OP_READ_LOCAL_FEATURES:
2161 hci_cc_read_local_features(hdev, skb);
2162 break;
2163
Andre Guedes971e3a42011-06-30 19:20:52 -03002164 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2165 hci_cc_read_local_ext_features(hdev, skb);
2166 break;
2167
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002168 case HCI_OP_READ_BUFFER_SIZE:
2169 hci_cc_read_buffer_size(hdev, skb);
2170 break;
2171
2172 case HCI_OP_READ_BD_ADDR:
2173 hci_cc_read_bd_addr(hdev, skb);
2174 break;
2175
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002176 case HCI_OP_READ_DATA_BLOCK_SIZE:
2177 hci_cc_read_data_block_size(hdev, skb);
2178 break;
2179
Johan Hedberg23bb5762010-12-21 23:01:27 +02002180 case HCI_OP_WRITE_CA_TIMEOUT:
2181 hci_cc_write_ca_timeout(hdev, skb);
2182 break;
2183
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002184 case HCI_OP_READ_FLOW_CONTROL_MODE:
2185 hci_cc_read_flow_control_mode(hdev, skb);
2186 break;
2187
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002188 case HCI_OP_READ_LOCAL_AMP_INFO:
2189 hci_cc_read_local_amp_info(hdev, skb);
2190 break;
2191
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002192 case HCI_OP_DELETE_STORED_LINK_KEY:
2193 hci_cc_delete_stored_link_key(hdev, skb);
2194 break;
2195
Johan Hedbergd5859e22011-01-25 01:19:58 +02002196 case HCI_OP_SET_EVENT_MASK:
2197 hci_cc_set_event_mask(hdev, skb);
2198 break;
2199
2200 case HCI_OP_WRITE_INQUIRY_MODE:
2201 hci_cc_write_inquiry_mode(hdev, skb);
2202 break;
2203
2204 case HCI_OP_READ_INQ_RSP_TX_POWER:
2205 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2206 break;
2207
2208 case HCI_OP_SET_EVENT_FLT:
2209 hci_cc_set_event_flt(hdev, skb);
2210 break;
2211
Johan Hedberg980e1a52011-01-22 06:10:07 +02002212 case HCI_OP_PIN_CODE_REPLY:
2213 hci_cc_pin_code_reply(hdev, skb);
2214 break;
2215
2216 case HCI_OP_PIN_CODE_NEG_REPLY:
2217 hci_cc_pin_code_neg_reply(hdev, skb);
2218 break;
2219
Szymon Jancc35938b2011-03-22 13:12:21 +01002220 case HCI_OP_READ_LOCAL_OOB_DATA:
2221 hci_cc_read_local_oob_data_reply(hdev, skb);
2222 break;
2223
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002224 case HCI_OP_LE_READ_BUFFER_SIZE:
2225 hci_cc_le_read_buffer_size(hdev, skb);
2226 break;
2227
Johan Hedberga5c29682011-02-19 12:05:57 -03002228 case HCI_OP_USER_CONFIRM_REPLY:
2229 hci_cc_user_confirm_reply(hdev, skb);
2230 break;
2231
2232 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2233 hci_cc_user_confirm_neg_reply(hdev, skb);
2234 break;
2235
Brian Gix1143d452011-11-23 08:28:34 -08002236 case HCI_OP_USER_PASSKEY_REPLY:
2237 hci_cc_user_passkey_reply(hdev, skb);
2238 break;
2239
2240 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2241 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002242
2243 case HCI_OP_LE_SET_SCAN_PARAM:
2244 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002245 break;
2246
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002247 case HCI_OP_LE_SET_SCAN_ENABLE:
2248 hci_cc_le_set_scan_enable(hdev, skb);
2249 break;
2250
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002251 case HCI_OP_LE_LTK_REPLY:
2252 hci_cc_le_ltk_reply(hdev, skb);
2253 break;
2254
2255 case HCI_OP_LE_LTK_NEG_REPLY:
2256 hci_cc_le_ltk_neg_reply(hdev, skb);
2257 break;
2258
Andre Guedesf9b49302011-06-30 19:20:53 -03002259 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2260 hci_cc_write_le_host_supported(hdev, skb);
2261 break;
2262
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002263 default:
2264 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2265 break;
2266 }
2267
Ville Tervo6bd32322011-02-16 16:32:41 +02002268 if (ev->opcode != HCI_OP_NOP)
2269 del_timer(&hdev->cmd_timer);
2270
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002271 if (ev->ncmd) {
2272 atomic_set(&hdev->cmd_cnt, 1);
2273 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002274 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002275 }
2276}
2277
2278static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2279{
2280 struct hci_ev_cmd_status *ev = (void *) skb->data;
2281 __u16 opcode;
2282
2283 skb_pull(skb, sizeof(*ev));
2284
2285 opcode = __le16_to_cpu(ev->opcode);
2286
2287 switch (opcode) {
2288 case HCI_OP_INQUIRY:
2289 hci_cs_inquiry(hdev, ev->status);
2290 break;
2291
2292 case HCI_OP_CREATE_CONN:
2293 hci_cs_create_conn(hdev, ev->status);
2294 break;
2295
2296 case HCI_OP_ADD_SCO:
2297 hci_cs_add_sco(hdev, ev->status);
2298 break;
2299
Marcel Holtmannf8558552008-07-14 20:13:49 +02002300 case HCI_OP_AUTH_REQUESTED:
2301 hci_cs_auth_requested(hdev, ev->status);
2302 break;
2303
2304 case HCI_OP_SET_CONN_ENCRYPT:
2305 hci_cs_set_conn_encrypt(hdev, ev->status);
2306 break;
2307
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002308 case HCI_OP_REMOTE_NAME_REQ:
2309 hci_cs_remote_name_req(hdev, ev->status);
2310 break;
2311
Marcel Holtmann769be972008-07-14 20:13:49 +02002312 case HCI_OP_READ_REMOTE_FEATURES:
2313 hci_cs_read_remote_features(hdev, ev->status);
2314 break;
2315
2316 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2317 hci_cs_read_remote_ext_features(hdev, ev->status);
2318 break;
2319
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002320 case HCI_OP_SETUP_SYNC_CONN:
2321 hci_cs_setup_sync_conn(hdev, ev->status);
2322 break;
2323
2324 case HCI_OP_SNIFF_MODE:
2325 hci_cs_sniff_mode(hdev, ev->status);
2326 break;
2327
2328 case HCI_OP_EXIT_SNIFF_MODE:
2329 hci_cs_exit_sniff_mode(hdev, ev->status);
2330 break;
2331
Johan Hedberg8962ee72011-01-20 12:40:27 +02002332 case HCI_OP_DISCONNECT:
2333 if (ev->status != 0)
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002334 mgmt_disconnect_failed(hdev, NULL, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002335 break;
2336
Ville Tervofcd89c02011-02-10 22:38:47 -03002337 case HCI_OP_LE_CREATE_CONN:
2338 hci_cs_le_create_conn(hdev, ev->status);
2339 break;
2340
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002341 case HCI_OP_LE_START_ENC:
2342 hci_cs_le_start_enc(hdev, ev->status);
2343 break;
2344
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002345 default:
2346 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2347 break;
2348 }
2349
Ville Tervo6bd32322011-02-16 16:32:41 +02002350 if (ev->opcode != HCI_OP_NOP)
2351 del_timer(&hdev->cmd_timer);
2352
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002353 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002354 atomic_set(&hdev->cmd_cnt, 1);
2355 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002356 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002357 }
2358}
2359
2360static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2361{
2362 struct hci_ev_role_change *ev = (void *) skb->data;
2363 struct hci_conn *conn;
2364
2365 BT_DBG("%s status %d", hdev->name, ev->status);
2366
2367 hci_dev_lock(hdev);
2368
2369 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2370 if (conn) {
2371 if (!ev->status) {
2372 if (ev->role)
2373 conn->link_mode &= ~HCI_LM_MASTER;
2374 else
2375 conn->link_mode |= HCI_LM_MASTER;
2376 }
2377
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002378 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002379
2380 hci_role_switch_cfm(conn, ev->status, ev->role);
2381 }
2382
2383 hci_dev_unlock(hdev);
2384}
2385
Linus Torvalds1da177e2005-04-16 15:20:36 -07002386static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2387{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002388 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389 int i;
2390
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002391 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2392 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2393 return;
2394 }
2395
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002396 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2397 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398 BT_DBG("%s bad parameters", hdev->name);
2399 return;
2400 }
2401
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002402 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2403
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002404 for (i = 0; i < ev->num_hndl; i++) {
2405 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406 struct hci_conn *conn;
2407 __u16 handle, count;
2408
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002409 handle = __le16_to_cpu(info->handle);
2410 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411
2412 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002413 if (!conn)
2414 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002416 conn->sent -= count;
2417
2418 switch (conn->type) {
2419 case ACL_LINK:
2420 hdev->acl_cnt += count;
2421 if (hdev->acl_cnt > hdev->acl_pkts)
2422 hdev->acl_cnt = hdev->acl_pkts;
2423 break;
2424
2425 case LE_LINK:
2426 if (hdev->le_pkts) {
2427 hdev->le_cnt += count;
2428 if (hdev->le_cnt > hdev->le_pkts)
2429 hdev->le_cnt = hdev->le_pkts;
2430 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002431 hdev->acl_cnt += count;
2432 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433 hdev->acl_cnt = hdev->acl_pkts;
2434 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002435 break;
2436
2437 case SCO_LINK:
2438 hdev->sco_cnt += count;
2439 if (hdev->sco_cnt > hdev->sco_pkts)
2440 hdev->sco_cnt = hdev->sco_pkts;
2441 break;
2442
2443 default:
2444 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2445 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446 }
2447 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002448
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002449 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450}
2451
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002452static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2453 struct sk_buff *skb)
2454{
2455 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2456 int i;
2457
2458 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2459 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2460 return;
2461 }
2462
2463 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2464 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2465 BT_DBG("%s bad parameters", hdev->name);
2466 return;
2467 }
2468
2469 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2470 ev->num_hndl);
2471
2472 for (i = 0; i < ev->num_hndl; i++) {
2473 struct hci_comp_blocks_info *info = &ev->handles[i];
2474 struct hci_conn *conn;
2475 __u16 handle, block_count;
2476
2477 handle = __le16_to_cpu(info->handle);
2478 block_count = __le16_to_cpu(info->blocks);
2479
2480 conn = hci_conn_hash_lookup_handle(hdev, handle);
2481 if (!conn)
2482 continue;
2483
2484 conn->sent -= block_count;
2485
2486 switch (conn->type) {
2487 case ACL_LINK:
2488 hdev->block_cnt += block_count;
2489 if (hdev->block_cnt > hdev->num_blocks)
2490 hdev->block_cnt = hdev->num_blocks;
2491 break;
2492
2493 default:
2494 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2495 break;
2496 }
2497 }
2498
2499 queue_work(hdev->workqueue, &hdev->tx_work);
2500}
2501
Marcel Holtmann04837f62006-07-03 10:02:33 +02002502static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002504 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002505 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002506
2507 BT_DBG("%s status %d", hdev->name, ev->status);
2508
2509 hci_dev_lock(hdev);
2510
Marcel Holtmann04837f62006-07-03 10:02:33 +02002511 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2512 if (conn) {
2513 conn->mode = ev->mode;
2514 conn->interval = __le16_to_cpu(ev->interval);
2515
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002516 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002517 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002518 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002519 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002520 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002521 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002522
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002523 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002524 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002525 }
2526
2527 hci_dev_unlock(hdev);
2528}
2529
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2531{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002532 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2533 struct hci_conn *conn;
2534
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002535 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002536
2537 hci_dev_lock(hdev);
2538
2539 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002540 if (!conn)
2541 goto unlock;
2542
2543 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002544 hci_conn_hold(conn);
2545 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2546 hci_conn_put(conn);
2547 }
2548
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002549 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002550 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2551 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002552 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002553 u8 secure;
2554
2555 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2556 secure = 1;
2557 else
2558 secure = 0;
2559
Johan Hedberg744cf192011-11-08 20:40:14 +02002560 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002561 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002562
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002563unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002564 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565}
2566
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2568{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002569 struct hci_ev_link_key_req *ev = (void *) skb->data;
2570 struct hci_cp_link_key_reply cp;
2571 struct hci_conn *conn;
2572 struct link_key *key;
2573
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002574 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002575
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002576 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002577 return;
2578
2579 hci_dev_lock(hdev);
2580
2581 key = hci_find_link_key(hdev, &ev->bdaddr);
2582 if (!key) {
2583 BT_DBG("%s link key not found for %s", hdev->name,
2584 batostr(&ev->bdaddr));
2585 goto not_found;
2586 }
2587
2588 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2589 batostr(&ev->bdaddr));
2590
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002591 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002592 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002593 BT_DBG("%s ignoring debug key", hdev->name);
2594 goto not_found;
2595 }
2596
2597 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002598 if (conn) {
2599 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2600 conn->auth_type != 0xff &&
2601 (conn->auth_type & 0x01)) {
2602 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2603 goto not_found;
2604 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002605
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002606 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2607 conn->pending_sec_level == BT_SECURITY_HIGH) {
2608 BT_DBG("%s ignoring key unauthenticated for high \
2609 security", hdev->name);
2610 goto not_found;
2611 }
2612
2613 conn->key_type = key->type;
2614 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002615 }
2616
2617 bacpy(&cp.bdaddr, &ev->bdaddr);
2618 memcpy(cp.link_key, key->val, 16);
2619
2620 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2621
2622 hci_dev_unlock(hdev);
2623
2624 return;
2625
2626not_found:
2627 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2628 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629}
2630
Linus Torvalds1da177e2005-04-16 15:20:36 -07002631static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2632{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002633 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2634 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002635 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002636
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002637 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002638
2639 hci_dev_lock(hdev);
2640
2641 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2642 if (conn) {
2643 hci_conn_hold(conn);
2644 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002645 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002646
2647 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2648 conn->key_type = ev->key_type;
2649
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002650 hci_conn_put(conn);
2651 }
2652
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002653 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002654 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002655 ev->key_type, pin_len);
2656
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002657 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658}
2659
Marcel Holtmann04837f62006-07-03 10:02:33 +02002660static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2661{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002662 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002663 struct hci_conn *conn;
2664
2665 BT_DBG("%s status %d", hdev->name, ev->status);
2666
2667 hci_dev_lock(hdev);
2668
2669 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670 if (conn && !ev->status) {
2671 struct inquiry_entry *ie;
2672
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002673 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2674 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002675 ie->data.clock_offset = ev->clock_offset;
2676 ie->timestamp = jiffies;
2677 }
2678 }
2679
2680 hci_dev_unlock(hdev);
2681}
2682
Marcel Holtmanna8746412008-07-14 20:13:46 +02002683static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2684{
2685 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2686 struct hci_conn *conn;
2687
2688 BT_DBG("%s status %d", hdev->name, ev->status);
2689
2690 hci_dev_lock(hdev);
2691
2692 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2693 if (conn && !ev->status)
2694 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2695
2696 hci_dev_unlock(hdev);
2697}
2698
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002699static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2700{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002701 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002702 struct inquiry_entry *ie;
2703
2704 BT_DBG("%s", hdev->name);
2705
2706 hci_dev_lock(hdev);
2707
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002708 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2709 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002710 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2711 ie->timestamp = jiffies;
2712 }
2713
2714 hci_dev_unlock(hdev);
2715}
2716
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002717static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2718{
2719 struct inquiry_data data;
2720 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg31754052012-01-04 13:39:52 +02002721 bool name_known;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002722
2723 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2724
2725 if (!num_rsp)
2726 return;
2727
2728 hci_dev_lock(hdev);
2729
2730 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002731 struct inquiry_info_with_rssi_and_pscan_mode *info;
2732 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002733
Johan Hedberge17acd42011-03-30 23:57:16 +03002734 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002735 bacpy(&data.bdaddr, &info->bdaddr);
2736 data.pscan_rep_mode = info->pscan_rep_mode;
2737 data.pscan_period_mode = info->pscan_period_mode;
2738 data.pscan_mode = info->pscan_mode;
2739 memcpy(data.dev_class, info->dev_class, 3);
2740 data.clock_offset = info->clock_offset;
2741 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002742 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002743
2744 name_known = hci_inquiry_cache_update(hdev, &data,
2745 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002746 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002747 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002748 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002749 }
2750 } else {
2751 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2752
Johan Hedberge17acd42011-03-30 23:57:16 +03002753 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002754 bacpy(&data.bdaddr, &info->bdaddr);
2755 data.pscan_rep_mode = info->pscan_rep_mode;
2756 data.pscan_period_mode = info->pscan_period_mode;
2757 data.pscan_mode = 0x00;
2758 memcpy(data.dev_class, info->dev_class, 3);
2759 data.clock_offset = info->clock_offset;
2760 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002761 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002762 name_known = hci_inquiry_cache_update(hdev, &data,
2763 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002764 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002765 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002766 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002767 }
2768 }
2769
2770 hci_dev_unlock(hdev);
2771}
2772
2773static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2774{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002775 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2776 struct hci_conn *conn;
2777
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002778 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002779
Marcel Holtmann41a96212008-07-14 20:13:48 +02002780 hci_dev_lock(hdev);
2781
2782 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002783 if (!conn)
2784 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002785
Johan Hedbergccd556f2010-11-10 17:11:51 +02002786 if (!ev->status && ev->page == 0x01) {
2787 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002788
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002789 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2790 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002791 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002792
Johan Hedberg58a681e2012-01-16 06:47:28 +02002793 if (ev->features[0] & 0x01)
2794 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002795 }
2796
Johan Hedbergccd556f2010-11-10 17:11:51 +02002797 if (conn->state != BT_CONFIG)
2798 goto unlock;
2799
Johan Hedberg127178d2010-11-18 22:22:29 +02002800 if (!ev->status) {
2801 struct hci_cp_remote_name_req cp;
2802 memset(&cp, 0, sizeof(cp));
2803 bacpy(&cp.bdaddr, &conn->dst);
2804 cp.pscan_rep_mode = 0x02;
2805 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002806 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2807 mgmt_device_connected(hdev, &conn->dst, conn->type,
2808 conn->dst_type, NULL, 0,
2809 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002810
Johan Hedberg127178d2010-11-18 22:22:29 +02002811 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002812 conn->state = BT_CONNECTED;
2813 hci_proto_connect_cfm(conn, ev->status);
2814 hci_conn_put(conn);
2815 }
2816
2817unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002818 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002819}
2820
2821static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2822{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002823 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2824 struct hci_conn *conn;
2825
2826 BT_DBG("%s status %d", hdev->name, ev->status);
2827
2828 hci_dev_lock(hdev);
2829
2830 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002831 if (!conn) {
2832 if (ev->link_type == ESCO_LINK)
2833 goto unlock;
2834
2835 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2836 if (!conn)
2837 goto unlock;
2838
2839 conn->type = SCO_LINK;
2840 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002841
Marcel Holtmann732547f2009-04-19 19:14:14 +02002842 switch (ev->status) {
2843 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002844 conn->handle = __le16_to_cpu(ev->handle);
2845 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002846
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002847 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002848 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002849 break;
2850
Stephen Coe705e5712010-02-16 11:29:44 -05002851 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002852 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002853 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002854 case 0x1f: /* Unspecified error */
2855 if (conn->out && conn->attempt < 2) {
2856 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2857 (hdev->esco_type & EDR_ESCO_MASK);
2858 hci_setup_sync(conn, conn->link->handle);
2859 goto unlock;
2860 }
2861 /* fall through */
2862
2863 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002864 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002865 break;
2866 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002867
2868 hci_proto_connect_cfm(conn, ev->status);
2869 if (ev->status)
2870 hci_conn_del(conn);
2871
2872unlock:
2873 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002874}
2875
2876static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2877{
2878 BT_DBG("%s", hdev->name);
2879}
2880
Marcel Holtmann04837f62006-07-03 10:02:33 +02002881static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2882{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002883 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002884
2885 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002886}
2887
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002888static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2889{
2890 struct inquiry_data data;
2891 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2892 int num_rsp = *((__u8 *) skb->data);
2893
2894 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2895
2896 if (!num_rsp)
2897 return;
2898
2899 hci_dev_lock(hdev);
2900
Johan Hedberge17acd42011-03-30 23:57:16 +03002901 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg561aafb2012-01-04 13:31:59 +02002902 bool name_known;
2903
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002904 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002905 data.pscan_rep_mode = info->pscan_rep_mode;
2906 data.pscan_period_mode = info->pscan_period_mode;
2907 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002908 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002909 data.clock_offset = info->clock_offset;
2910 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002911 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002912
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002913 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002914 name_known = eir_has_data_type(info->data,
2915 sizeof(info->data),
2916 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002917 else
2918 name_known = true;
2919
Johan Hedberg31754052012-01-04 13:39:52 +02002920 name_known = hci_inquiry_cache_update(hdev, &data, name_known);
Johan Hedberg48264f02011-11-09 13:58:58 +02002921 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002922 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002923 !name_known, info->data,
2924 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002925 }
2926
2927 hci_dev_unlock(hdev);
2928}
2929
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002930static inline u8 hci_get_auth_req(struct hci_conn *conn)
2931{
2932 /* If remote requests dedicated bonding follow that lead */
2933 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2934 /* If both remote and local IO capabilities allow MITM
2935 * protection then require it, otherwise don't */
2936 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2937 return 0x02;
2938 else
2939 return 0x03;
2940 }
2941
2942 /* If remote requests no-bonding follow that lead */
2943 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002944 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002945
2946 return conn->auth_type;
2947}
2948
Marcel Holtmann04936842008-07-14 20:13:48 +02002949static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2950{
2951 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2952 struct hci_conn *conn;
2953
2954 BT_DBG("%s", hdev->name);
2955
2956 hci_dev_lock(hdev);
2957
2958 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002959 if (!conn)
2960 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002961
Johan Hedberg03b555e2011-01-04 15:40:05 +02002962 hci_conn_hold(conn);
2963
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002964 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002965 goto unlock;
2966
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002967 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02002968 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002969 struct hci_cp_io_capability_reply cp;
2970
2971 bacpy(&cp.bdaddr, &ev->bdaddr);
2972 cp.capability = conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07002973 conn->auth_type = hci_get_auth_req(conn);
2974 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002975
Johan Hedberg58a681e2012-01-16 06:47:28 +02002976 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01002977 hci_find_remote_oob_data(hdev, &conn->dst))
2978 cp.oob_data = 0x01;
2979 else
2980 cp.oob_data = 0x00;
2981
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002982 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2983 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002984 } else {
2985 struct hci_cp_io_capability_neg_reply cp;
2986
2987 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002988 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02002989
2990 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2991 sizeof(cp), &cp);
2992 }
2993
2994unlock:
2995 hci_dev_unlock(hdev);
2996}
2997
2998static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2999{
3000 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3001 struct hci_conn *conn;
3002
3003 BT_DBG("%s", hdev->name);
3004
3005 hci_dev_lock(hdev);
3006
3007 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3008 if (!conn)
3009 goto unlock;
3010
Johan Hedberg03b555e2011-01-04 15:40:05 +02003011 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003012 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003013 if (ev->oob_data)
3014 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003015
3016unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003017 hci_dev_unlock(hdev);
3018}
3019
Johan Hedberga5c29682011-02-19 12:05:57 -03003020static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3021 struct sk_buff *skb)
3022{
3023 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003024 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003025 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003026
3027 BT_DBG("%s", hdev->name);
3028
3029 hci_dev_lock(hdev);
3030
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003031 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003032 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003033
Johan Hedberg7a828902011-04-28 11:28:53 -07003034 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3035 if (!conn)
3036 goto unlock;
3037
3038 loc_mitm = (conn->auth_type & 0x01);
3039 rem_mitm = (conn->remote_auth & 0x01);
3040
3041 /* If we require MITM but the remote device can't provide that
3042 * (it has NoInputNoOutput) then reject the confirmation
3043 * request. The only exception is when we're dedicated bonding
3044 * initiators (connect_cfm_cb set) since then we always have the MITM
3045 * bit set. */
3046 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3047 BT_DBG("Rejecting request: remote device can't provide MITM");
3048 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3049 sizeof(ev->bdaddr), &ev->bdaddr);
3050 goto unlock;
3051 }
3052
3053 /* If no side requires MITM protection; auto-accept */
3054 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3055 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003056
3057 /* If we're not the initiators request authorization to
3058 * proceed from user space (mgmt_user_confirm with
3059 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003060 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003061 BT_DBG("Confirming auto-accept as acceptor");
3062 confirm_hint = 1;
3063 goto confirm;
3064 }
3065
Johan Hedberg9f616562011-04-28 11:28:54 -07003066 BT_DBG("Auto-accept of user confirmation with %ums delay",
3067 hdev->auto_accept_delay);
3068
3069 if (hdev->auto_accept_delay > 0) {
3070 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3071 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3072 goto unlock;
3073 }
3074
Johan Hedberg7a828902011-04-28 11:28:53 -07003075 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3076 sizeof(ev->bdaddr), &ev->bdaddr);
3077 goto unlock;
3078 }
3079
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003080confirm:
Johan Hedberg744cf192011-11-08 20:40:14 +02003081 mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003082 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003083
3084unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003085 hci_dev_unlock(hdev);
3086}
3087
Brian Gix1143d452011-11-23 08:28:34 -08003088static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3089 struct sk_buff *skb)
3090{
3091 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3092
3093 BT_DBG("%s", hdev->name);
3094
3095 hci_dev_lock(hdev);
3096
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003097 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08003098 mgmt_user_passkey_request(hdev, &ev->bdaddr);
3099
3100 hci_dev_unlock(hdev);
3101}
3102
Marcel Holtmann04936842008-07-14 20:13:48 +02003103static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3104{
3105 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3106 struct hci_conn *conn;
3107
3108 BT_DBG("%s", hdev->name);
3109
3110 hci_dev_lock(hdev);
3111
3112 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003113 if (!conn)
3114 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003115
Johan Hedberg2a611692011-02-19 12:06:00 -03003116 /* To avoid duplicate auth_failed events to user space we check
3117 * the HCI_CONN_AUTH_PEND flag which will be set if we
3118 * initiated the authentication. A traditional auth_complete
3119 * event gets always produced as initiator and is also mapped to
3120 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003121 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedberg744cf192011-11-08 20:40:14 +02003122 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003123
3124 hci_conn_put(conn);
3125
3126unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003127 hci_dev_unlock(hdev);
3128}
3129
Marcel Holtmann41a96212008-07-14 20:13:48 +02003130static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3131{
3132 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3133 struct inquiry_entry *ie;
3134
3135 BT_DBG("%s", hdev->name);
3136
3137 hci_dev_lock(hdev);
3138
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003139 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3140 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003141 ie->data.ssp_mode = (ev->features[0] & 0x01);
3142
3143 hci_dev_unlock(hdev);
3144}
3145
Szymon Janc2763eda2011-03-22 13:12:22 +01003146static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3147 struct sk_buff *skb)
3148{
3149 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3150 struct oob_data *data;
3151
3152 BT_DBG("%s", hdev->name);
3153
3154 hci_dev_lock(hdev);
3155
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003156 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003157 goto unlock;
3158
Szymon Janc2763eda2011-03-22 13:12:22 +01003159 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3160 if (data) {
3161 struct hci_cp_remote_oob_data_reply cp;
3162
3163 bacpy(&cp.bdaddr, &ev->bdaddr);
3164 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3165 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3166
3167 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3168 &cp);
3169 } else {
3170 struct hci_cp_remote_oob_data_neg_reply cp;
3171
3172 bacpy(&cp.bdaddr, &ev->bdaddr);
3173 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3174 &cp);
3175 }
3176
Szymon Jance1ba1f12011-04-06 13:01:59 +02003177unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003178 hci_dev_unlock(hdev);
3179}
3180
Ville Tervofcd89c02011-02-10 22:38:47 -03003181static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3182{
3183 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3184 struct hci_conn *conn;
3185
3186 BT_DBG("%s status %d", hdev->name, ev->status);
3187
3188 hci_dev_lock(hdev);
3189
3190 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003191 if (!conn) {
3192 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3193 if (!conn) {
3194 BT_ERR("No memory for new connection");
3195 hci_dev_unlock(hdev);
3196 return;
3197 }
Andre Guedes29b79882011-05-31 14:20:54 -03003198
3199 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003200 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003201
3202 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003203 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3204 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003205 hci_proto_connect_cfm(conn, ev->status);
3206 conn->state = BT_CLOSED;
3207 hci_conn_del(conn);
3208 goto unlock;
3209 }
3210
Johan Hedbergb644ba32012-01-17 21:48:47 +02003211 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3212 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3213 conn->dst_type, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003214
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003215 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003216 conn->handle = __le16_to_cpu(ev->handle);
3217 conn->state = BT_CONNECTED;
3218
3219 hci_conn_hold_device(conn);
3220 hci_conn_add_sysfs(conn);
3221
3222 hci_proto_connect_cfm(conn, ev->status);
3223
3224unlock:
3225 hci_dev_unlock(hdev);
3226}
3227
Andre Guedes9aa04c92011-05-26 16:23:51 -03003228static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3229 struct sk_buff *skb)
3230{
Andre Guedese95beb42011-09-26 20:48:35 -03003231 u8 num_reports = skb->data[0];
3232 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003233 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003234
3235 hci_dev_lock(hdev);
3236
Andre Guedese95beb42011-09-26 20:48:35 -03003237 while (num_reports--) {
3238 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003239
Andre Guedes9aa04c92011-05-26 16:23:51 -03003240 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003241
Andre Guedes3c9e9192012-01-10 18:20:50 -03003242 rssi = ev->data[ev->length];
3243 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3244 NULL, rssi, 0, ev->data, ev->length);
3245
Andre Guedese95beb42011-09-26 20:48:35 -03003246 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003247 }
3248
3249 hci_dev_unlock(hdev);
3250}
3251
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003252static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3253 struct sk_buff *skb)
3254{
3255 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3256 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003257 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003258 struct hci_conn *conn;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003259 struct link_key *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003260
3261 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3262
3263 hci_dev_lock(hdev);
3264
3265 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003266 if (conn == NULL)
3267 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003268
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003269 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3270 if (ltk == NULL)
3271 goto not_found;
3272
3273 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003274 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes726b4ff2011-07-08 18:31:45 -03003275 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003276
3277 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3278
3279 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003280
3281 return;
3282
3283not_found:
3284 neg.handle = ev->handle;
3285 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3286 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003287}
3288
Ville Tervofcd89c02011-02-10 22:38:47 -03003289static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3290{
3291 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3292
3293 skb_pull(skb, sizeof(*le_ev));
3294
3295 switch (le_ev->subevent) {
3296 case HCI_EV_LE_CONN_COMPLETE:
3297 hci_le_conn_complete_evt(hdev, skb);
3298 break;
3299
Andre Guedes9aa04c92011-05-26 16:23:51 -03003300 case HCI_EV_LE_ADVERTISING_REPORT:
3301 hci_le_adv_report_evt(hdev, skb);
3302 break;
3303
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003304 case HCI_EV_LE_LTK_REQ:
3305 hci_le_ltk_request_evt(hdev, skb);
3306 break;
3307
Ville Tervofcd89c02011-02-10 22:38:47 -03003308 default:
3309 break;
3310 }
3311}
3312
Linus Torvalds1da177e2005-04-16 15:20:36 -07003313void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3314{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003315 struct hci_event_hdr *hdr = (void *) skb->data;
3316 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003317
3318 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3319
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003320 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003321 case HCI_EV_INQUIRY_COMPLETE:
3322 hci_inquiry_complete_evt(hdev, skb);
3323 break;
3324
3325 case HCI_EV_INQUIRY_RESULT:
3326 hci_inquiry_result_evt(hdev, skb);
3327 break;
3328
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003329 case HCI_EV_CONN_COMPLETE:
3330 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003331 break;
3332
Linus Torvalds1da177e2005-04-16 15:20:36 -07003333 case HCI_EV_CONN_REQUEST:
3334 hci_conn_request_evt(hdev, skb);
3335 break;
3336
Linus Torvalds1da177e2005-04-16 15:20:36 -07003337 case HCI_EV_DISCONN_COMPLETE:
3338 hci_disconn_complete_evt(hdev, skb);
3339 break;
3340
Linus Torvalds1da177e2005-04-16 15:20:36 -07003341 case HCI_EV_AUTH_COMPLETE:
3342 hci_auth_complete_evt(hdev, skb);
3343 break;
3344
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003345 case HCI_EV_REMOTE_NAME:
3346 hci_remote_name_evt(hdev, skb);
3347 break;
3348
Linus Torvalds1da177e2005-04-16 15:20:36 -07003349 case HCI_EV_ENCRYPT_CHANGE:
3350 hci_encrypt_change_evt(hdev, skb);
3351 break;
3352
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003353 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3354 hci_change_link_key_complete_evt(hdev, skb);
3355 break;
3356
3357 case HCI_EV_REMOTE_FEATURES:
3358 hci_remote_features_evt(hdev, skb);
3359 break;
3360
3361 case HCI_EV_REMOTE_VERSION:
3362 hci_remote_version_evt(hdev, skb);
3363 break;
3364
3365 case HCI_EV_QOS_SETUP_COMPLETE:
3366 hci_qos_setup_complete_evt(hdev, skb);
3367 break;
3368
3369 case HCI_EV_CMD_COMPLETE:
3370 hci_cmd_complete_evt(hdev, skb);
3371 break;
3372
3373 case HCI_EV_CMD_STATUS:
3374 hci_cmd_status_evt(hdev, skb);
3375 break;
3376
3377 case HCI_EV_ROLE_CHANGE:
3378 hci_role_change_evt(hdev, skb);
3379 break;
3380
3381 case HCI_EV_NUM_COMP_PKTS:
3382 hci_num_comp_pkts_evt(hdev, skb);
3383 break;
3384
3385 case HCI_EV_MODE_CHANGE:
3386 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003387 break;
3388
3389 case HCI_EV_PIN_CODE_REQ:
3390 hci_pin_code_request_evt(hdev, skb);
3391 break;
3392
3393 case HCI_EV_LINK_KEY_REQ:
3394 hci_link_key_request_evt(hdev, skb);
3395 break;
3396
3397 case HCI_EV_LINK_KEY_NOTIFY:
3398 hci_link_key_notify_evt(hdev, skb);
3399 break;
3400
3401 case HCI_EV_CLOCK_OFFSET:
3402 hci_clock_offset_evt(hdev, skb);
3403 break;
3404
Marcel Holtmanna8746412008-07-14 20:13:46 +02003405 case HCI_EV_PKT_TYPE_CHANGE:
3406 hci_pkt_type_change_evt(hdev, skb);
3407 break;
3408
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003409 case HCI_EV_PSCAN_REP_MODE:
3410 hci_pscan_rep_mode_evt(hdev, skb);
3411 break;
3412
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003413 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3414 hci_inquiry_result_with_rssi_evt(hdev, skb);
3415 break;
3416
3417 case HCI_EV_REMOTE_EXT_FEATURES:
3418 hci_remote_ext_features_evt(hdev, skb);
3419 break;
3420
3421 case HCI_EV_SYNC_CONN_COMPLETE:
3422 hci_sync_conn_complete_evt(hdev, skb);
3423 break;
3424
3425 case HCI_EV_SYNC_CONN_CHANGED:
3426 hci_sync_conn_changed_evt(hdev, skb);
3427 break;
3428
Marcel Holtmann04837f62006-07-03 10:02:33 +02003429 case HCI_EV_SNIFF_SUBRATE:
3430 hci_sniff_subrate_evt(hdev, skb);
3431 break;
3432
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003433 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3434 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003435 break;
3436
Marcel Holtmann04936842008-07-14 20:13:48 +02003437 case HCI_EV_IO_CAPA_REQUEST:
3438 hci_io_capa_request_evt(hdev, skb);
3439 break;
3440
Johan Hedberg03b555e2011-01-04 15:40:05 +02003441 case HCI_EV_IO_CAPA_REPLY:
3442 hci_io_capa_reply_evt(hdev, skb);
3443 break;
3444
Johan Hedberga5c29682011-02-19 12:05:57 -03003445 case HCI_EV_USER_CONFIRM_REQUEST:
3446 hci_user_confirm_request_evt(hdev, skb);
3447 break;
3448
Brian Gix1143d452011-11-23 08:28:34 -08003449 case HCI_EV_USER_PASSKEY_REQUEST:
3450 hci_user_passkey_request_evt(hdev, skb);
3451 break;
3452
Marcel Holtmann04936842008-07-14 20:13:48 +02003453 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3454 hci_simple_pair_complete_evt(hdev, skb);
3455 break;
3456
Marcel Holtmann41a96212008-07-14 20:13:48 +02003457 case HCI_EV_REMOTE_HOST_FEATURES:
3458 hci_remote_host_features_evt(hdev, skb);
3459 break;
3460
Ville Tervofcd89c02011-02-10 22:38:47 -03003461 case HCI_EV_LE_META:
3462 hci_le_meta_evt(hdev, skb);
3463 break;
3464
Szymon Janc2763eda2011-03-22 13:12:22 +01003465 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3466 hci_remote_oob_data_request_evt(hdev, skb);
3467 break;
3468
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003469 case HCI_EV_NUM_COMP_BLOCKS:
3470 hci_num_comp_blocks_evt(hdev, skb);
3471 break;
3472
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003473 default:
3474 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003475 break;
3476 }
3477
3478 kfree_skb(skb);
3479 hdev->stat.evt_rx++;
3480}
3481
3482/* Generate internal stack event */
3483void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3484{
3485 struct hci_event_hdr *hdr;
3486 struct hci_ev_stack_internal *ev;
3487 struct sk_buff *skb;
3488
3489 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3490 if (!skb)
3491 return;
3492
3493 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3494 hdr->evt = HCI_EV_STACK_INTERNAL;
3495 hdr->plen = sizeof(*ev) + dlen;
3496
3497 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3498 ev->type = type;
3499 memcpy(ev->data, data, dlen);
3500
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003501 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003502 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003503
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003504 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003505 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003506 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003507 kfree_skb(skb);
3508}
Andre Guedese6100a22011-06-30 19:20:54 -03003509
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003510module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003511MODULE_PARM_DESC(enable_le, "Enable LE support");