blob: 5fb1ee516d3a081f1e4e46cd0cda40372db78f8d [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <net/sock.h>
39
40#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020041#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <asm/unaligned.h>
43
44#include <net/bluetooth/bluetooth.h>
45#include <net/bluetooth/hci_core.h>
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047/* Handle HCI Event packets */
48
Marcel Holtmanna9de9242007-10-20 13:33:56 +020049static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070050{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020051 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
Marcel Holtmanna9de9242007-10-20 13:33:56 +020053 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Andre Guedese6d465c2011-11-09 17:14:26 -030055 if (status) {
56 hci_dev_lock(hdev);
57 mgmt_stop_discovery_failed(hdev, status);
58 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020059 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030060 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
Andre Guedes89352e72011-11-04 14:16:53 -030062 clear_bit(HCI_INQUIRY, &hdev->flags);
63
Johan Hedberg56e5cb82011-11-08 20:40:16 +020064 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020065 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020066 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010067
Johan Hedberg23bb5762010-12-21 23:01:27 +020068 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010069
Marcel Holtmanna9de9242007-10-20 13:33:56 +020070 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070071}
72
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020075 __u8 status = *((__u8 *) skb->data);
76
77 BT_DBG("%s status 0x%x", hdev->name, status);
78
79 if (status)
80 return;
81
Marcel Holtmanna9de9242007-10-20 13:33:56 +020082 hci_conn_check_pending(hdev);
83}
84
85static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
86{
87 BT_DBG("%s", hdev->name);
88}
89
90static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
91{
92 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 if (rp->status)
98 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200102 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
103 if (conn) {
104 if (rp->role)
105 conn->link_mode &= ~HCI_LM_MASTER;
106 else
107 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200109
110 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111}
112
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200113static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
114{
115 struct hci_rp_read_link_policy *rp = (void *) skb->data;
116 struct hci_conn *conn;
117
118 BT_DBG("%s status 0x%x", hdev->name, rp->status);
119
120 if (rp->status)
121 return;
122
123 hci_dev_lock(hdev);
124
125 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
126 if (conn)
127 conn->link_policy = __le16_to_cpu(rp->policy);
128
129 hci_dev_unlock(hdev);
130}
131
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200132static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200134 struct hci_rp_write_link_policy *rp = (void *) skb->data;
135 struct hci_conn *conn;
136 void *sent;
137
138 BT_DBG("%s status 0x%x", hdev->name, rp->status);
139
140 if (rp->status)
141 return;
142
143 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
144 if (!sent)
145 return;
146
147 hci_dev_lock(hdev);
148
149 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200150 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700151 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200152
153 hci_dev_unlock(hdev);
154}
155
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200156static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
157{
158 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
159
160 BT_DBG("%s status 0x%x", hdev->name, rp->status);
161
162 if (rp->status)
163 return;
164
165 hdev->link_policy = __le16_to_cpu(rp->policy);
166}
167
168static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
169{
170 __u8 status = *((__u8 *) skb->data);
171 void *sent;
172
173 BT_DBG("%s status 0x%x", hdev->name, status);
174
175 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
176 if (!sent)
177 return;
178
179 if (!status)
180 hdev->link_policy = get_unaligned_le16(sent);
181
Johan Hedberg23bb5762010-12-21 23:01:27 +0200182 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200183}
184
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200185static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
186{
187 __u8 status = *((__u8 *) skb->data);
188
189 BT_DBG("%s status 0x%x", hdev->name, status);
190
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300191 clear_bit(HCI_RESET, &hdev->flags);
192
Johan Hedberg23bb5762010-12-21 23:01:27 +0200193 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300194
Johan Hedberga297e972012-02-21 17:55:47 +0200195 /* Reset all non-persistent flags */
196 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200197}
198
199static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
200{
201 __u8 status = *((__u8 *) skb->data);
202 void *sent;
203
204 BT_DBG("%s status 0x%x", hdev->name, status);
205
206 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
207 if (!sent)
208 return;
209
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200210 hci_dev_lock(hdev);
211
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200212 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200213 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200214
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200215 if (status == 0)
216 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200219}
220
221static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
222{
223 struct hci_rp_read_local_name *rp = (void *) skb->data;
224
225 BT_DBG("%s status 0x%x", hdev->name, rp->status);
226
227 if (rp->status)
228 return;
229
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200230 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200231}
232
233static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
234{
235 __u8 status = *((__u8 *) skb->data);
236 void *sent;
237
238 BT_DBG("%s status 0x%x", hdev->name, status);
239
240 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
241 if (!sent)
242 return;
243
244 if (!status) {
245 __u8 param = *((__u8 *) sent);
246
247 if (param == AUTH_ENABLED)
248 set_bit(HCI_AUTH, &hdev->flags);
249 else
250 clear_bit(HCI_AUTH, &hdev->flags);
251 }
252
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200253 if (test_bit(HCI_MGMT, &hdev->dev_flags))
254 mgmt_auth_enable_complete(hdev, status);
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)
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200446 goto done;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200447
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);
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200456
457done:
458 if (test_bit(HCI_MGMT, &hdev->dev_flags))
459 mgmt_ssp_enable_complete(hdev, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200460}
461
Johan Hedbergd5859e22011-01-25 01:19:58 +0200462static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
463{
464 if (hdev->features[6] & LMP_EXT_INQ)
465 return 2;
466
467 if (hdev->features[3] & LMP_RSSI_INQ)
468 return 1;
469
470 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
471 hdev->lmp_subver == 0x0757)
472 return 1;
473
474 if (hdev->manufacturer == 15) {
475 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
476 return 1;
477 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
478 return 1;
479 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
480 return 1;
481 }
482
483 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
484 hdev->lmp_subver == 0x1805)
485 return 1;
486
487 return 0;
488}
489
490static void hci_setup_inquiry_mode(struct hci_dev *hdev)
491{
492 u8 mode;
493
494 mode = hci_get_inquiry_mode(hdev);
495
496 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
497}
498
499static void hci_setup_event_mask(struct hci_dev *hdev)
500{
501 /* The second byte is 0xff instead of 0x9f (two reserved bits
502 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
503 * command otherwise */
504 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
505
Ville Tervo6de6c182011-05-27 11:16:21 +0300506 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
507 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200508 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300509 return;
510
511 events[4] |= 0x01; /* Flow Specification Complete */
512 events[4] |= 0x02; /* Inquiry Result with RSSI */
513 events[4] |= 0x04; /* Read Remote Extended Features Complete */
514 events[5] |= 0x08; /* Synchronous Connection Complete */
515 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200516
517 if (hdev->features[3] & LMP_RSSI_INQ)
518 events[4] |= 0x04; /* Inquiry Result with RSSI */
519
520 if (hdev->features[5] & LMP_SNIFF_SUBR)
521 events[5] |= 0x20; /* Sniff Subrating */
522
523 if (hdev->features[5] & LMP_PAUSE_ENC)
524 events[5] |= 0x80; /* Encryption Key Refresh Complete */
525
526 if (hdev->features[6] & LMP_EXT_INQ)
527 events[5] |= 0x40; /* Extended Inquiry Result */
528
529 if (hdev->features[6] & LMP_NO_FLUSH)
530 events[7] |= 0x01; /* Enhanced Flush Complete */
531
532 if (hdev->features[7] & LMP_LSTO)
533 events[6] |= 0x80; /* Link Supervision Timeout Changed */
534
535 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
536 events[6] |= 0x01; /* IO Capability Request */
537 events[6] |= 0x02; /* IO Capability Response */
538 events[6] |= 0x04; /* User Confirmation Request */
539 events[6] |= 0x08; /* User Passkey Request */
540 events[6] |= 0x10; /* Remote OOB Data Request */
541 events[6] |= 0x20; /* Simple Pairing Complete */
542 events[7] |= 0x04; /* User Passkey Notification */
543 events[7] |= 0x08; /* Keypress Notification */
544 events[7] |= 0x10; /* Remote Host Supported
545 * Features Notification */
546 }
547
548 if (hdev->features[4] & LMP_LE)
549 events[7] |= 0x20; /* LE Meta-Event */
550
551 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
552}
553
Andre Guedese6100a22011-06-30 19:20:54 -0300554static void hci_set_le_support(struct hci_dev *hdev)
555{
556 struct hci_cp_write_le_host_supported cp;
557
558 memset(&cp, 0, sizeof(cp));
559
560 if (enable_le) {
561 cp.le = 1;
562 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
563 }
564
565 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
566}
567
Johan Hedbergd5859e22011-01-25 01:19:58 +0200568static void hci_setup(struct hci_dev *hdev)
569{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200570 if (hdev->dev_type != HCI_BREDR)
571 return;
572
Johan Hedbergd5859e22011-01-25 01:19:58 +0200573 hci_setup_event_mask(hdev);
574
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200575 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200576 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
577
578 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
579 u8 mode = 0x01;
580 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
581 }
582
583 if (hdev->features[3] & LMP_RSSI_INQ)
584 hci_setup_inquiry_mode(hdev);
585
586 if (hdev->features[7] & LMP_INQ_TX_PWR)
587 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300588
589 if (hdev->features[7] & LMP_EXTFEATURES) {
590 struct hci_cp_read_local_ext_features cp;
591
592 cp.page = 0x01;
593 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
594 sizeof(cp), &cp);
595 }
Andre Guedese6100a22011-06-30 19:20:54 -0300596
Johan Hedberg47990ea2012-02-22 11:58:37 +0200597 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
598 u8 enable = 1;
599 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE,
600 sizeof(enable), &enable);
601 }
602
Andre Guedese6100a22011-06-30 19:20:54 -0300603 if (hdev->features[4] & LMP_LE)
604 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200605}
606
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200607static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
608{
609 struct hci_rp_read_local_version *rp = (void *) skb->data;
610
611 BT_DBG("%s status 0x%x", hdev->name, rp->status);
612
613 if (rp->status)
614 return;
615
616 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200617 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200618 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200619 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200620 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200621
622 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
623 hdev->manufacturer,
624 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200625
626 if (test_bit(HCI_INIT, &hdev->flags))
627 hci_setup(hdev);
628}
629
630static void hci_setup_link_policy(struct hci_dev *hdev)
631{
632 u16 link_policy = 0;
633
634 if (hdev->features[0] & LMP_RSWITCH)
635 link_policy |= HCI_LP_RSWITCH;
636 if (hdev->features[0] & LMP_HOLD)
637 link_policy |= HCI_LP_HOLD;
638 if (hdev->features[0] & LMP_SNIFF)
639 link_policy |= HCI_LP_SNIFF;
640 if (hdev->features[1] & LMP_PARK)
641 link_policy |= HCI_LP_PARK;
642
643 link_policy = cpu_to_le16(link_policy);
644 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
645 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200646}
647
648static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
649{
650 struct hci_rp_read_local_commands *rp = (void *) skb->data;
651
652 BT_DBG("%s status 0x%x", hdev->name, rp->status);
653
654 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200655 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200656
657 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200658
659 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
660 hci_setup_link_policy(hdev);
661
662done:
663 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200664}
665
666static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
667{
668 struct hci_rp_read_local_features *rp = (void *) skb->data;
669
670 BT_DBG("%s status 0x%x", hdev->name, rp->status);
671
672 if (rp->status)
673 return;
674
675 memcpy(hdev->features, rp->features, 8);
676
677 /* Adjust default settings according to features
678 * supported by device. */
679
680 if (hdev->features[0] & LMP_3SLOT)
681 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
682
683 if (hdev->features[0] & LMP_5SLOT)
684 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
685
686 if (hdev->features[1] & LMP_HV2) {
687 hdev->pkt_type |= (HCI_HV2);
688 hdev->esco_type |= (ESCO_HV2);
689 }
690
691 if (hdev->features[1] & LMP_HV3) {
692 hdev->pkt_type |= (HCI_HV3);
693 hdev->esco_type |= (ESCO_HV3);
694 }
695
696 if (hdev->features[3] & LMP_ESCO)
697 hdev->esco_type |= (ESCO_EV3);
698
699 if (hdev->features[4] & LMP_EV4)
700 hdev->esco_type |= (ESCO_EV4);
701
702 if (hdev->features[4] & LMP_EV5)
703 hdev->esco_type |= (ESCO_EV5);
704
Marcel Holtmannefc76882009-02-06 09:13:37 +0100705 if (hdev->features[5] & LMP_EDR_ESCO_2M)
706 hdev->esco_type |= (ESCO_2EV3);
707
708 if (hdev->features[5] & LMP_EDR_ESCO_3M)
709 hdev->esco_type |= (ESCO_3EV3);
710
711 if (hdev->features[5] & LMP_EDR_3S_ESCO)
712 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
713
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200714 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
715 hdev->features[0], hdev->features[1],
716 hdev->features[2], hdev->features[3],
717 hdev->features[4], hdev->features[5],
718 hdev->features[6], hdev->features[7]);
719}
720
Andre Guedes971e3a42011-06-30 19:20:52 -0300721static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
722 struct sk_buff *skb)
723{
724 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
725
726 BT_DBG("%s status 0x%x", hdev->name, rp->status);
727
728 if (rp->status)
729 return;
730
Andre Guedesb5b32b62011-12-30 10:34:04 -0300731 switch (rp->page) {
732 case 0:
733 memcpy(hdev->features, rp->features, 8);
734 break;
735 case 1:
736 memcpy(hdev->host_features, rp->features, 8);
737 break;
738 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300739
740 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
741}
742
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200743static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
744 struct sk_buff *skb)
745{
746 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
747
748 BT_DBG("%s status 0x%x", hdev->name, rp->status);
749
750 if (rp->status)
751 return;
752
753 hdev->flow_ctl_mode = rp->mode;
754
755 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
756}
757
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200758static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
759{
760 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
761
762 BT_DBG("%s status 0x%x", hdev->name, rp->status);
763
764 if (rp->status)
765 return;
766
767 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
768 hdev->sco_mtu = rp->sco_mtu;
769 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
770 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
771
772 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
773 hdev->sco_mtu = 64;
774 hdev->sco_pkts = 8;
775 }
776
777 hdev->acl_cnt = hdev->acl_pkts;
778 hdev->sco_cnt = hdev->sco_pkts;
779
780 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
781 hdev->acl_mtu, hdev->acl_pkts,
782 hdev->sco_mtu, hdev->sco_pkts);
783}
784
785static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
786{
787 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
788
789 BT_DBG("%s status 0x%x", hdev->name, rp->status);
790
791 if (!rp->status)
792 bacpy(&hdev->bdaddr, &rp->bdaddr);
793
Johan Hedberg23bb5762010-12-21 23:01:27 +0200794 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
795}
796
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200797static void hci_cc_read_data_block_size(struct hci_dev *hdev,
798 struct sk_buff *skb)
799{
800 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
801
802 BT_DBG("%s status 0x%x", hdev->name, rp->status);
803
804 if (rp->status)
805 return;
806
807 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
808 hdev->block_len = __le16_to_cpu(rp->block_len);
809 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
810
811 hdev->block_cnt = hdev->num_blocks;
812
813 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
814 hdev->block_cnt, hdev->block_len);
815
816 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
817}
818
Johan Hedberg23bb5762010-12-21 23:01:27 +0200819static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
820{
821 __u8 status = *((__u8 *) skb->data);
822
823 BT_DBG("%s status 0x%x", hdev->name, status);
824
825 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200826}
827
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300828static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
829 struct sk_buff *skb)
830{
831 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
832
833 BT_DBG("%s status 0x%x", hdev->name, rp->status);
834
835 if (rp->status)
836 return;
837
838 hdev->amp_status = rp->amp_status;
839 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
840 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
841 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
842 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
843 hdev->amp_type = rp->amp_type;
844 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
845 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
846 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
847 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
848
849 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
850}
851
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200852static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
853 struct sk_buff *skb)
854{
855 __u8 status = *((__u8 *) skb->data);
856
857 BT_DBG("%s status 0x%x", hdev->name, status);
858
859 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
860}
861
Johan Hedbergd5859e22011-01-25 01:19:58 +0200862static void hci_cc_set_event_mask(struct hci_dev *hdev, 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_SET_EVENT_MASK, status);
869}
870
871static void hci_cc_write_inquiry_mode(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_WRITE_INQUIRY_MODE, status);
879}
880
881static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
882 struct sk_buff *skb)
883{
884 __u8 status = *((__u8 *) skb->data);
885
886 BT_DBG("%s status 0x%x", hdev->name, status);
887
888 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
889}
890
891static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
892{
893 __u8 status = *((__u8 *) skb->data);
894
895 BT_DBG("%s status 0x%x", hdev->name, status);
896
897 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
898}
899
Johan Hedberg980e1a52011-01-22 06:10:07 +0200900static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
901{
902 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
903 struct hci_cp_pin_code_reply *cp;
904 struct hci_conn *conn;
905
906 BT_DBG("%s status 0x%x", hdev->name, rp->status);
907
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200908 hci_dev_lock(hdev);
909
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200910 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200911 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200912
913 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200914 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200915
916 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
917 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200918 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200919
920 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
921 if (conn)
922 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200923
924unlock:
925 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200926}
927
928static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
929{
930 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
931
932 BT_DBG("%s status 0x%x", hdev->name, rp->status);
933
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200934 hci_dev_lock(hdev);
935
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200936 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200937 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200938 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200939
940 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200941}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200942
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300943static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
944 struct sk_buff *skb)
945{
946 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
947
948 BT_DBG("%s status 0x%x", hdev->name, rp->status);
949
950 if (rp->status)
951 return;
952
953 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
954 hdev->le_pkts = rp->le_max_pkt;
955
956 hdev->le_cnt = hdev->le_pkts;
957
958 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
959
960 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
961}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200962
Johan Hedberga5c29682011-02-19 12:05:57 -0300963static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
964{
965 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
966
967 BT_DBG("%s status 0x%x", hdev->name, rp->status);
968
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200969 hci_dev_lock(hdev);
970
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200971 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200972 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
973 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200974
975 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300976}
977
978static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
979 struct sk_buff *skb)
980{
981 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
982
983 BT_DBG("%s status 0x%x", hdev->name, rp->status);
984
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200985 hci_dev_lock(hdev);
986
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200987 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200988 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200989 ACL_LINK, 0,
Johan Hedberga5c29682011-02-19 12:05:57 -0300990 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200991
992 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300993}
994
Brian Gix1143d452011-11-23 08:28:34 -0800995static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
996{
997 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
998
999 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1000
1001 hci_dev_lock(hdev);
1002
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001003 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001004 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1005 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001006
1007 hci_dev_unlock(hdev);
1008}
1009
1010static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1011 struct sk_buff *skb)
1012{
1013 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1014
1015 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1016
1017 hci_dev_lock(hdev);
1018
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001019 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001020 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001021 ACL_LINK, 0,
Brian Gix1143d452011-11-23 08:28:34 -08001022 rp->status);
1023
1024 hci_dev_unlock(hdev);
1025}
1026
Szymon Jancc35938b2011-03-22 13:12:21 +01001027static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1028 struct sk_buff *skb)
1029{
1030 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1031
1032 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1033
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001034 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001035 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001036 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001037 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001038}
1039
Andre Guedes07f7fa52011-12-02 21:13:31 +09001040static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1041{
1042 __u8 status = *((__u8 *) skb->data);
1043
1044 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001045
1046 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001047
1048 if (status) {
1049 hci_dev_lock(hdev);
1050 mgmt_start_discovery_failed(hdev, status);
1051 hci_dev_unlock(hdev);
1052 return;
1053 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001054}
1055
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001056static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1057 struct sk_buff *skb)
1058{
1059 struct hci_cp_le_set_scan_enable *cp;
1060 __u8 status = *((__u8 *) skb->data);
1061
1062 BT_DBG("%s status 0x%x", hdev->name, status);
1063
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001064 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1065 if (!cp)
1066 return;
1067
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001068 switch (cp->enable) {
1069 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001070 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1071
Andre Guedes3fd24152012-02-03 17:48:01 -03001072 if (status) {
1073 hci_dev_lock(hdev);
1074 mgmt_start_discovery_failed(hdev, status);
1075 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001076 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001077 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001078
Andre Guedesd23264a2011-11-25 20:53:38 -03001079 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1080
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001081 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001082
1083 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001084 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001085 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001086 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001087 break;
1088
1089 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001090 if (status)
1091 return;
1092
Andre Guedesd23264a2011-11-25 20:53:38 -03001093 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1094
Andre Guedesd0843292012-01-02 19:18:11 -03001095 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001096
1097 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1098 mgmt_interleaved_discovery(hdev);
1099 } else {
1100 hci_dev_lock(hdev);
1101 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1102 hci_dev_unlock(hdev);
1103 }
1104
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001105 break;
1106
1107 default:
1108 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1109 break;
Andre Guedes35815082011-05-26 16:23:53 -03001110 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001111}
1112
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001113static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1114{
1115 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1116
1117 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1118
1119 if (rp->status)
1120 return;
1121
1122 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1123}
1124
1125static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1126{
1127 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1128
1129 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1130
1131 if (rp->status)
1132 return;
1133
1134 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1135}
1136
Andre Guedesf9b49302011-06-30 19:20:53 -03001137static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1138 struct sk_buff *skb)
1139{
1140 struct hci_cp_read_local_ext_features cp;
1141 __u8 status = *((__u8 *) skb->data);
1142
1143 BT_DBG("%s status 0x%x", hdev->name, status);
1144
1145 if (status)
1146 return;
1147
1148 cp.page = 0x01;
1149 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1150}
1151
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001152static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1153{
1154 BT_DBG("%s status 0x%x", hdev->name, status);
1155
1156 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001157 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001158 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001159 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001160 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001161 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001162 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001163 return;
1164 }
1165
Andre Guedes89352e72011-11-04 14:16:53 -03001166 set_bit(HCI_INQUIRY, &hdev->flags);
1167
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001168 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001169 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001170 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001171}
1172
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1174{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001175 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001178 BT_DBG("%s status 0x%x", hdev->name, status);
1179
1180 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 if (!cp)
1182 return;
1183
1184 hci_dev_lock(hdev);
1185
1186 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1187
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001188 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189
1190 if (status) {
1191 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001192 if (status != 0x0c || conn->attempt > 2) {
1193 conn->state = BT_CLOSED;
1194 hci_proto_connect_cfm(conn, status);
1195 hci_conn_del(conn);
1196 } else
1197 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 }
1199 } else {
1200 if (!conn) {
1201 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1202 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001203 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 conn->link_mode |= HCI_LM_MASTER;
1205 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001206 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 }
1208 }
1209
1210 hci_dev_unlock(hdev);
1211}
1212
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001213static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001215 struct hci_cp_add_sco *cp;
1216 struct hci_conn *acl, *sco;
1217 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001219 BT_DBG("%s status 0x%x", hdev->name, status);
1220
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001221 if (!status)
1222 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001224 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1225 if (!cp)
1226 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001228 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001230 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001231
1232 hci_dev_lock(hdev);
1233
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001234 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001235 if (acl) {
1236 sco = acl->link;
1237 if (sco) {
1238 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001239
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001240 hci_proto_connect_cfm(sco, status);
1241 hci_conn_del(sco);
1242 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001243 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001244
1245 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246}
1247
Marcel Holtmannf8558552008-07-14 20:13:49 +02001248static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1249{
1250 struct hci_cp_auth_requested *cp;
1251 struct hci_conn *conn;
1252
1253 BT_DBG("%s status 0x%x", hdev->name, status);
1254
1255 if (!status)
1256 return;
1257
1258 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1259 if (!cp)
1260 return;
1261
1262 hci_dev_lock(hdev);
1263
1264 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1265 if (conn) {
1266 if (conn->state == BT_CONFIG) {
1267 hci_proto_connect_cfm(conn, status);
1268 hci_conn_put(conn);
1269 }
1270 }
1271
1272 hci_dev_unlock(hdev);
1273}
1274
1275static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1276{
1277 struct hci_cp_set_conn_encrypt *cp;
1278 struct hci_conn *conn;
1279
1280 BT_DBG("%s status 0x%x", hdev->name, status);
1281
1282 if (!status)
1283 return;
1284
1285 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1286 if (!cp)
1287 return;
1288
1289 hci_dev_lock(hdev);
1290
1291 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1292 if (conn) {
1293 if (conn->state == BT_CONFIG) {
1294 hci_proto_connect_cfm(conn, status);
1295 hci_conn_put(conn);
1296 }
1297 }
1298
1299 hci_dev_unlock(hdev);
1300}
1301
Johan Hedberg127178d2010-11-18 22:22:29 +02001302static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001303 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001304{
Johan Hedberg392599b2010-11-18 22:22:28 +02001305 if (conn->state != BT_CONFIG || !conn->out)
1306 return 0;
1307
Johan Hedberg765c2a92011-01-19 12:06:52 +05301308 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001309 return 0;
1310
1311 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001312 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001313 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001314 conn->pending_sec_level != BT_SECURITY_HIGH &&
1315 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001316 return 0;
1317
Johan Hedberg392599b2010-11-18 22:22:28 +02001318 return 1;
1319}
1320
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001321static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1322{
1323 struct hci_cp_remote_name_req cp;
1324
1325 memset(&cp, 0, sizeof(cp));
1326
1327 bacpy(&cp.bdaddr, &e->data.bdaddr);
1328 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1329 cp.pscan_mode = e->data.pscan_mode;
1330 cp.clock_offset = e->data.clock_offset;
1331
1332 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1333}
1334
Johan Hedbergb644ba32012-01-17 21:48:47 +02001335static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001336{
1337 struct discovery_state *discov = &hdev->discovery;
1338 struct inquiry_entry *e;
1339
Johan Hedbergb644ba32012-01-17 21:48:47 +02001340 if (list_empty(&discov->resolve))
1341 return false;
1342
1343 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1344 if (hci_resolve_name(hdev, e) == 0) {
1345 e->name_state = NAME_PENDING;
1346 return true;
1347 }
1348
1349 return false;
1350}
1351
1352static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1353 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1354{
1355 struct discovery_state *discov = &hdev->discovery;
1356 struct inquiry_entry *e;
1357
1358 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1359 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
1360 name, name_len, conn->dev_class);
1361
1362 if (discov->state == DISCOVERY_STOPPED)
1363 return;
1364
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001365 if (discov->state == DISCOVERY_STOPPING)
1366 goto discov_complete;
1367
1368 if (discov->state != DISCOVERY_RESOLVING)
1369 return;
1370
1371 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1372 if (e) {
1373 e->name_state = NAME_KNOWN;
1374 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001375 if (name)
1376 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1377 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001378 }
1379
Johan Hedbergb644ba32012-01-17 21:48:47 +02001380 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001381 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001382
1383discov_complete:
1384 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1385}
1386
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001387static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1388{
Johan Hedberg127178d2010-11-18 22:22:29 +02001389 struct hci_cp_remote_name_req *cp;
1390 struct hci_conn *conn;
1391
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001392 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001393
1394 /* If successful wait for the name req complete event before
1395 * checking for the need to do authentication */
1396 if (!status)
1397 return;
1398
1399 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1400 if (!cp)
1401 return;
1402
1403 hci_dev_lock(hdev);
1404
1405 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001406
1407 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1408 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1409
Johan Hedberg79c6c702011-04-28 11:28:55 -07001410 if (!conn)
1411 goto unlock;
1412
1413 if (!hci_outgoing_auth_needed(hdev, conn))
1414 goto unlock;
1415
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001416 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001417 struct hci_cp_auth_requested cp;
1418 cp.handle = __cpu_to_le16(conn->handle);
1419 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1420 }
1421
Johan Hedberg79c6c702011-04-28 11:28:55 -07001422unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001423 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001424}
1425
Marcel Holtmann769be972008-07-14 20:13:49 +02001426static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1427{
1428 struct hci_cp_read_remote_features *cp;
1429 struct hci_conn *conn;
1430
1431 BT_DBG("%s status 0x%x", hdev->name, status);
1432
1433 if (!status)
1434 return;
1435
1436 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1437 if (!cp)
1438 return;
1439
1440 hci_dev_lock(hdev);
1441
1442 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1443 if (conn) {
1444 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001445 hci_proto_connect_cfm(conn, status);
1446 hci_conn_put(conn);
1447 }
1448 }
1449
1450 hci_dev_unlock(hdev);
1451}
1452
1453static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1454{
1455 struct hci_cp_read_remote_ext_features *cp;
1456 struct hci_conn *conn;
1457
1458 BT_DBG("%s status 0x%x", hdev->name, status);
1459
1460 if (!status)
1461 return;
1462
1463 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1464 if (!cp)
1465 return;
1466
1467 hci_dev_lock(hdev);
1468
1469 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1470 if (conn) {
1471 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001472 hci_proto_connect_cfm(conn, status);
1473 hci_conn_put(conn);
1474 }
1475 }
1476
1477 hci_dev_unlock(hdev);
1478}
1479
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001480static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1481{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001482 struct hci_cp_setup_sync_conn *cp;
1483 struct hci_conn *acl, *sco;
1484 __u16 handle;
1485
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001486 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001487
1488 if (!status)
1489 return;
1490
1491 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1492 if (!cp)
1493 return;
1494
1495 handle = __le16_to_cpu(cp->handle);
1496
1497 BT_DBG("%s handle %d", hdev->name, handle);
1498
1499 hci_dev_lock(hdev);
1500
1501 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001502 if (acl) {
1503 sco = acl->link;
1504 if (sco) {
1505 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001506
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001507 hci_proto_connect_cfm(sco, status);
1508 hci_conn_del(sco);
1509 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001510 }
1511
1512 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001513}
1514
1515static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1516{
1517 struct hci_cp_sniff_mode *cp;
1518 struct hci_conn *conn;
1519
1520 BT_DBG("%s status 0x%x", hdev->name, status);
1521
1522 if (!status)
1523 return;
1524
1525 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1526 if (!cp)
1527 return;
1528
1529 hci_dev_lock(hdev);
1530
1531 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001532 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001533 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001534
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001535 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001536 hci_sco_setup(conn, status);
1537 }
1538
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001539 hci_dev_unlock(hdev);
1540}
1541
1542static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1543{
1544 struct hci_cp_exit_sniff_mode *cp;
1545 struct hci_conn *conn;
1546
1547 BT_DBG("%s status 0x%x", hdev->name, status);
1548
1549 if (!status)
1550 return;
1551
1552 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1553 if (!cp)
1554 return;
1555
1556 hci_dev_lock(hdev);
1557
1558 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001559 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001560 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001561
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001562 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001563 hci_sco_setup(conn, status);
1564 }
1565
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001566 hci_dev_unlock(hdev);
1567}
1568
Johan Hedberg88c3df12012-02-09 14:27:38 +02001569static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1570{
1571 struct hci_cp_disconnect *cp;
1572 struct hci_conn *conn;
1573
1574 if (!status)
1575 return;
1576
1577 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1578 if (!cp)
1579 return;
1580
1581 hci_dev_lock(hdev);
1582
1583 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1584 if (conn)
1585 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1586 conn->dst_type, status);
1587
1588 hci_dev_unlock(hdev);
1589}
1590
Ville Tervofcd89c02011-02-10 22:38:47 -03001591static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1592{
1593 struct hci_cp_le_create_conn *cp;
1594 struct hci_conn *conn;
1595
1596 BT_DBG("%s status 0x%x", hdev->name, status);
1597
1598 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1599 if (!cp)
1600 return;
1601
1602 hci_dev_lock(hdev);
1603
1604 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1605
1606 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1607 conn);
1608
1609 if (status) {
1610 if (conn && conn->state == BT_CONNECT) {
1611 conn->state = BT_CLOSED;
1612 hci_proto_connect_cfm(conn, status);
1613 hci_conn_del(conn);
1614 }
1615 } else {
1616 if (!conn) {
1617 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001618 if (conn) {
1619 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001620 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001621 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001622 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001623 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001624 }
1625 }
1626
1627 hci_dev_unlock(hdev);
1628}
1629
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001630static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1631{
1632 BT_DBG("%s status 0x%x", hdev->name, status);
1633}
1634
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001635static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1636{
1637 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001638 struct discovery_state *discov = &hdev->discovery;
1639 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001640
1641 BT_DBG("%s status %d", hdev->name, status);
1642
Johan Hedberg23bb5762010-12-21 23:01:27 +02001643 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001644
1645 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001646
1647 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1648 return;
1649
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001650 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001651 return;
1652
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001653 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001654
Andre Guedes343f9352012-02-17 20:39:37 -03001655 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001656 goto unlock;
1657
1658 if (list_empty(&discov->resolve)) {
1659 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1660 goto unlock;
1661 }
1662
1663 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1664 if (e && hci_resolve_name(hdev, e) == 0) {
1665 e->name_state = NAME_PENDING;
1666 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1667 } else {
1668 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1669 }
1670
1671unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001672 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001673}
1674
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1676{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001677 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001678 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 int num_rsp = *((__u8 *) skb->data);
1680
1681 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1682
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001683 if (!num_rsp)
1684 return;
1685
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001687
Johan Hedberge17acd42011-03-30 23:57:16 +03001688 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg31754052012-01-04 13:39:52 +02001689 bool name_known;
1690
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691 bacpy(&data.bdaddr, &info->bdaddr);
1692 data.pscan_rep_mode = info->pscan_rep_mode;
1693 data.pscan_period_mode = info->pscan_period_mode;
1694 data.pscan_mode = info->pscan_mode;
1695 memcpy(data.dev_class, info->dev_class, 3);
1696 data.clock_offset = info->clock_offset;
1697 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001698 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001699
1700 name_known = hci_inquiry_cache_update(hdev, &data, false);
Johan Hedberg48264f02011-11-09 13:58:58 +02001701 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Andre Guedes7d262f82012-01-10 18:20:49 -03001702 info->dev_class, 0, !name_known,
1703 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001705
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 hci_dev_unlock(hdev);
1707}
1708
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001709static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001711 struct hci_ev_conn_complete *ev = (void *) skb->data;
1712 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001714 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001715
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001717
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001718 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001719 if (!conn) {
1720 if (ev->link_type != SCO_LINK)
1721 goto unlock;
1722
1723 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1724 if (!conn)
1725 goto unlock;
1726
1727 conn->type = SCO_LINK;
1728 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001729
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001730 if (!ev->status) {
1731 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001732
1733 if (conn->type == ACL_LINK) {
1734 conn->state = BT_CONFIG;
1735 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001736 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001737 } else
1738 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001739
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001740 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001741 hci_conn_add_sysfs(conn);
1742
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001743 if (test_bit(HCI_AUTH, &hdev->flags))
1744 conn->link_mode |= HCI_LM_AUTH;
1745
1746 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1747 conn->link_mode |= HCI_LM_ENCRYPT;
1748
1749 /* Get remote features */
1750 if (conn->type == ACL_LINK) {
1751 struct hci_cp_read_remote_features cp;
1752 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001753 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1754 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001755 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001756
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001757 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001758 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001759 struct hci_cp_change_conn_ptype cp;
1760 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001761 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1762 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1763 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001764 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001765 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001766 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001767 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001768 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001769 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001770 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001771
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001772 if (conn->type == ACL_LINK)
1773 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001774
Marcel Holtmann769be972008-07-14 20:13:49 +02001775 if (ev->status) {
1776 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001777 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001778 } else if (ev->link_type != ACL_LINK)
1779 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001780
1781unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001783
1784 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785}
1786
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1788{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001789 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 int mask = hdev->link_mode;
1791
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001792 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1793 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794
1795 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1796
Szymon Janc138d22e2011-02-17 16:44:23 +01001797 if ((mask & HCI_LM_ACCEPT) &&
1798 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001800 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802
1803 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001804
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001805 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1806 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001807 memcpy(ie->data.dev_class, ev->dev_class, 3);
1808
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1810 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001811 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1812 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001813 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 hci_dev_unlock(hdev);
1815 return;
1816 }
1817 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001818
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 memcpy(conn->dev_class, ev->dev_class, 3);
1820 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001821
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 hci_dev_unlock(hdev);
1823
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001824 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1825 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001827 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001829 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1830 cp.role = 0x00; /* Become master */
1831 else
1832 cp.role = 0x01; /* Remain slave */
1833
1834 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1835 sizeof(cp), &cp);
1836 } else {
1837 struct hci_cp_accept_sync_conn_req cp;
1838
1839 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001840 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001841
1842 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1843 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1844 cp.max_latency = cpu_to_le16(0xffff);
1845 cp.content_format = cpu_to_le16(hdev->voice_setting);
1846 cp.retrans_effort = 0xff;
1847
1848 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1849 sizeof(cp), &cp);
1850 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 } else {
1852 /* Connection rejected */
1853 struct hci_cp_reject_conn_req cp;
1854
1855 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001856 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001857 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 }
1859}
1860
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1862{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001863 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001864 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865
1866 BT_DBG("%s status %d", hdev->name, ev->status);
1867
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 hci_dev_lock(hdev);
1869
Marcel Holtmann04837f62006-07-03 10:02:33 +02001870 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001871 if (!conn)
1872 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001873
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001874 if (ev->status == 0)
1875 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876
Johan Hedbergb644ba32012-01-17 21:48:47 +02001877 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1878 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001879 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001880 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1881 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001882 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001883 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001884 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001885 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001886
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001887 if (ev->status == 0) {
1888 hci_proto_disconn_cfm(conn, ev->reason);
1889 hci_conn_del(conn);
1890 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001891
1892unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 hci_dev_unlock(hdev);
1894}
1895
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001896static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1897{
1898 struct hci_ev_auth_complete *ev = (void *) skb->data;
1899 struct hci_conn *conn;
1900
1901 BT_DBG("%s status %d", hdev->name, ev->status);
1902
1903 hci_dev_lock(hdev);
1904
1905 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001906 if (!conn)
1907 goto unlock;
1908
1909 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001910 if (!hci_conn_ssp_enabled(conn) &&
1911 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001912 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001913 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001914 conn->link_mode |= HCI_LM_AUTH;
1915 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001916 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001917 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001918 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
1919 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001920 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001921
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001922 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1923 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001924
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001925 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001926 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001927 struct hci_cp_set_conn_encrypt cp;
1928 cp.handle = ev->handle;
1929 cp.encrypt = 0x01;
1930 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1931 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001932 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001933 conn->state = BT_CONNECTED;
1934 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001935 hci_conn_put(conn);
1936 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001937 } else {
1938 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001939
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001940 hci_conn_hold(conn);
1941 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1942 hci_conn_put(conn);
1943 }
1944
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001945 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001946 if (!ev->status) {
1947 struct hci_cp_set_conn_encrypt cp;
1948 cp.handle = ev->handle;
1949 cp.encrypt = 0x01;
1950 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1951 &cp);
1952 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001953 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001954 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001955 }
1956 }
1957
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001958unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001959 hci_dev_unlock(hdev);
1960}
1961
1962static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1963{
Johan Hedberg127178d2010-11-18 22:22:29 +02001964 struct hci_ev_remote_name *ev = (void *) skb->data;
1965 struct hci_conn *conn;
1966
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001967 BT_DBG("%s", hdev->name);
1968
1969 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001970
1971 hci_dev_lock(hdev);
1972
1973 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001974
1975 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1976 goto check_auth;
1977
1978 if (ev->status == 0)
1979 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1980 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1981 else
1982 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1983
1984check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001985 if (!conn)
1986 goto unlock;
1987
1988 if (!hci_outgoing_auth_needed(hdev, conn))
1989 goto unlock;
1990
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001991 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001992 struct hci_cp_auth_requested cp;
1993 cp.handle = __cpu_to_le16(conn->handle);
1994 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1995 }
1996
Johan Hedberg79c6c702011-04-28 11:28:55 -07001997unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001998 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001999}
2000
2001static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2002{
2003 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2004 struct hci_conn *conn;
2005
2006 BT_DBG("%s status %d", hdev->name, ev->status);
2007
2008 hci_dev_lock(hdev);
2009
2010 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2011 if (conn) {
2012 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002013 if (ev->encrypt) {
2014 /* Encryption implies authentication */
2015 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002016 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002017 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002018 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002019 conn->link_mode &= ~HCI_LM_ENCRYPT;
2020 }
2021
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002022 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002023
Marcel Holtmannf8558552008-07-14 20:13:49 +02002024 if (conn->state == BT_CONFIG) {
2025 if (!ev->status)
2026 conn->state = BT_CONNECTED;
2027
2028 hci_proto_connect_cfm(conn, ev->status);
2029 hci_conn_put(conn);
2030 } else
2031 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002032 }
2033
2034 hci_dev_unlock(hdev);
2035}
2036
2037static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2038{
2039 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2040 struct hci_conn *conn;
2041
2042 BT_DBG("%s status %d", hdev->name, ev->status);
2043
2044 hci_dev_lock(hdev);
2045
2046 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2047 if (conn) {
2048 if (!ev->status)
2049 conn->link_mode |= HCI_LM_SECURE;
2050
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002051 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002052
2053 hci_key_change_cfm(conn, ev->status);
2054 }
2055
2056 hci_dev_unlock(hdev);
2057}
2058
2059static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2060{
2061 struct hci_ev_remote_features *ev = (void *) skb->data;
2062 struct hci_conn *conn;
2063
2064 BT_DBG("%s status %d", hdev->name, ev->status);
2065
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002066 hci_dev_lock(hdev);
2067
2068 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002069 if (!conn)
2070 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002071
Johan Hedbergccd556f2010-11-10 17:11:51 +02002072 if (!ev->status)
2073 memcpy(conn->features, ev->features, 8);
2074
2075 if (conn->state != BT_CONFIG)
2076 goto unlock;
2077
2078 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2079 struct hci_cp_read_remote_ext_features cp;
2080 cp.handle = ev->handle;
2081 cp.page = 0x01;
2082 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002083 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002084 goto unlock;
2085 }
2086
Johan Hedberg127178d2010-11-18 22:22:29 +02002087 if (!ev->status) {
2088 struct hci_cp_remote_name_req cp;
2089 memset(&cp, 0, sizeof(cp));
2090 bacpy(&cp.bdaddr, &conn->dst);
2091 cp.pscan_rep_mode = 0x02;
2092 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002093 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2094 mgmt_device_connected(hdev, &conn->dst, conn->type,
2095 conn->dst_type, NULL, 0,
2096 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002097
Johan Hedberg127178d2010-11-18 22:22:29 +02002098 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002099 conn->state = BT_CONNECTED;
2100 hci_proto_connect_cfm(conn, ev->status);
2101 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002102 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002103
Johan Hedbergccd556f2010-11-10 17:11:51 +02002104unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002105 hci_dev_unlock(hdev);
2106}
2107
2108static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2109{
2110 BT_DBG("%s", hdev->name);
2111}
2112
2113static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2114{
2115 BT_DBG("%s", hdev->name);
2116}
2117
2118static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2119{
2120 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2121 __u16 opcode;
2122
2123 skb_pull(skb, sizeof(*ev));
2124
2125 opcode = __le16_to_cpu(ev->opcode);
2126
2127 switch (opcode) {
2128 case HCI_OP_INQUIRY_CANCEL:
2129 hci_cc_inquiry_cancel(hdev, skb);
2130 break;
2131
2132 case HCI_OP_EXIT_PERIODIC_INQ:
2133 hci_cc_exit_periodic_inq(hdev, skb);
2134 break;
2135
2136 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2137 hci_cc_remote_name_req_cancel(hdev, skb);
2138 break;
2139
2140 case HCI_OP_ROLE_DISCOVERY:
2141 hci_cc_role_discovery(hdev, skb);
2142 break;
2143
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002144 case HCI_OP_READ_LINK_POLICY:
2145 hci_cc_read_link_policy(hdev, skb);
2146 break;
2147
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002148 case HCI_OP_WRITE_LINK_POLICY:
2149 hci_cc_write_link_policy(hdev, skb);
2150 break;
2151
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002152 case HCI_OP_READ_DEF_LINK_POLICY:
2153 hci_cc_read_def_link_policy(hdev, skb);
2154 break;
2155
2156 case HCI_OP_WRITE_DEF_LINK_POLICY:
2157 hci_cc_write_def_link_policy(hdev, skb);
2158 break;
2159
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002160 case HCI_OP_RESET:
2161 hci_cc_reset(hdev, skb);
2162 break;
2163
2164 case HCI_OP_WRITE_LOCAL_NAME:
2165 hci_cc_write_local_name(hdev, skb);
2166 break;
2167
2168 case HCI_OP_READ_LOCAL_NAME:
2169 hci_cc_read_local_name(hdev, skb);
2170 break;
2171
2172 case HCI_OP_WRITE_AUTH_ENABLE:
2173 hci_cc_write_auth_enable(hdev, skb);
2174 break;
2175
2176 case HCI_OP_WRITE_ENCRYPT_MODE:
2177 hci_cc_write_encrypt_mode(hdev, skb);
2178 break;
2179
2180 case HCI_OP_WRITE_SCAN_ENABLE:
2181 hci_cc_write_scan_enable(hdev, skb);
2182 break;
2183
2184 case HCI_OP_READ_CLASS_OF_DEV:
2185 hci_cc_read_class_of_dev(hdev, skb);
2186 break;
2187
2188 case HCI_OP_WRITE_CLASS_OF_DEV:
2189 hci_cc_write_class_of_dev(hdev, skb);
2190 break;
2191
2192 case HCI_OP_READ_VOICE_SETTING:
2193 hci_cc_read_voice_setting(hdev, skb);
2194 break;
2195
2196 case HCI_OP_WRITE_VOICE_SETTING:
2197 hci_cc_write_voice_setting(hdev, skb);
2198 break;
2199
2200 case HCI_OP_HOST_BUFFER_SIZE:
2201 hci_cc_host_buffer_size(hdev, skb);
2202 break;
2203
Marcel Holtmann333140b2008-07-14 20:13:48 +02002204 case HCI_OP_READ_SSP_MODE:
2205 hci_cc_read_ssp_mode(hdev, skb);
2206 break;
2207
2208 case HCI_OP_WRITE_SSP_MODE:
2209 hci_cc_write_ssp_mode(hdev, skb);
2210 break;
2211
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002212 case HCI_OP_READ_LOCAL_VERSION:
2213 hci_cc_read_local_version(hdev, skb);
2214 break;
2215
2216 case HCI_OP_READ_LOCAL_COMMANDS:
2217 hci_cc_read_local_commands(hdev, skb);
2218 break;
2219
2220 case HCI_OP_READ_LOCAL_FEATURES:
2221 hci_cc_read_local_features(hdev, skb);
2222 break;
2223
Andre Guedes971e3a42011-06-30 19:20:52 -03002224 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2225 hci_cc_read_local_ext_features(hdev, skb);
2226 break;
2227
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002228 case HCI_OP_READ_BUFFER_SIZE:
2229 hci_cc_read_buffer_size(hdev, skb);
2230 break;
2231
2232 case HCI_OP_READ_BD_ADDR:
2233 hci_cc_read_bd_addr(hdev, skb);
2234 break;
2235
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002236 case HCI_OP_READ_DATA_BLOCK_SIZE:
2237 hci_cc_read_data_block_size(hdev, skb);
2238 break;
2239
Johan Hedberg23bb5762010-12-21 23:01:27 +02002240 case HCI_OP_WRITE_CA_TIMEOUT:
2241 hci_cc_write_ca_timeout(hdev, skb);
2242 break;
2243
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002244 case HCI_OP_READ_FLOW_CONTROL_MODE:
2245 hci_cc_read_flow_control_mode(hdev, skb);
2246 break;
2247
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002248 case HCI_OP_READ_LOCAL_AMP_INFO:
2249 hci_cc_read_local_amp_info(hdev, skb);
2250 break;
2251
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002252 case HCI_OP_DELETE_STORED_LINK_KEY:
2253 hci_cc_delete_stored_link_key(hdev, skb);
2254 break;
2255
Johan Hedbergd5859e22011-01-25 01:19:58 +02002256 case HCI_OP_SET_EVENT_MASK:
2257 hci_cc_set_event_mask(hdev, skb);
2258 break;
2259
2260 case HCI_OP_WRITE_INQUIRY_MODE:
2261 hci_cc_write_inquiry_mode(hdev, skb);
2262 break;
2263
2264 case HCI_OP_READ_INQ_RSP_TX_POWER:
2265 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2266 break;
2267
2268 case HCI_OP_SET_EVENT_FLT:
2269 hci_cc_set_event_flt(hdev, skb);
2270 break;
2271
Johan Hedberg980e1a52011-01-22 06:10:07 +02002272 case HCI_OP_PIN_CODE_REPLY:
2273 hci_cc_pin_code_reply(hdev, skb);
2274 break;
2275
2276 case HCI_OP_PIN_CODE_NEG_REPLY:
2277 hci_cc_pin_code_neg_reply(hdev, skb);
2278 break;
2279
Szymon Jancc35938b2011-03-22 13:12:21 +01002280 case HCI_OP_READ_LOCAL_OOB_DATA:
2281 hci_cc_read_local_oob_data_reply(hdev, skb);
2282 break;
2283
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002284 case HCI_OP_LE_READ_BUFFER_SIZE:
2285 hci_cc_le_read_buffer_size(hdev, skb);
2286 break;
2287
Johan Hedberga5c29682011-02-19 12:05:57 -03002288 case HCI_OP_USER_CONFIRM_REPLY:
2289 hci_cc_user_confirm_reply(hdev, skb);
2290 break;
2291
2292 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2293 hci_cc_user_confirm_neg_reply(hdev, skb);
2294 break;
2295
Brian Gix1143d452011-11-23 08:28:34 -08002296 case HCI_OP_USER_PASSKEY_REPLY:
2297 hci_cc_user_passkey_reply(hdev, skb);
2298 break;
2299
2300 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2301 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002302
2303 case HCI_OP_LE_SET_SCAN_PARAM:
2304 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002305 break;
2306
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002307 case HCI_OP_LE_SET_SCAN_ENABLE:
2308 hci_cc_le_set_scan_enable(hdev, skb);
2309 break;
2310
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002311 case HCI_OP_LE_LTK_REPLY:
2312 hci_cc_le_ltk_reply(hdev, skb);
2313 break;
2314
2315 case HCI_OP_LE_LTK_NEG_REPLY:
2316 hci_cc_le_ltk_neg_reply(hdev, skb);
2317 break;
2318
Andre Guedesf9b49302011-06-30 19:20:53 -03002319 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2320 hci_cc_write_le_host_supported(hdev, skb);
2321 break;
2322
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002323 default:
2324 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2325 break;
2326 }
2327
Ville Tervo6bd32322011-02-16 16:32:41 +02002328 if (ev->opcode != HCI_OP_NOP)
2329 del_timer(&hdev->cmd_timer);
2330
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002331 if (ev->ncmd) {
2332 atomic_set(&hdev->cmd_cnt, 1);
2333 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002334 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002335 }
2336}
2337
2338static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2339{
2340 struct hci_ev_cmd_status *ev = (void *) skb->data;
2341 __u16 opcode;
2342
2343 skb_pull(skb, sizeof(*ev));
2344
2345 opcode = __le16_to_cpu(ev->opcode);
2346
2347 switch (opcode) {
2348 case HCI_OP_INQUIRY:
2349 hci_cs_inquiry(hdev, ev->status);
2350 break;
2351
2352 case HCI_OP_CREATE_CONN:
2353 hci_cs_create_conn(hdev, ev->status);
2354 break;
2355
2356 case HCI_OP_ADD_SCO:
2357 hci_cs_add_sco(hdev, ev->status);
2358 break;
2359
Marcel Holtmannf8558552008-07-14 20:13:49 +02002360 case HCI_OP_AUTH_REQUESTED:
2361 hci_cs_auth_requested(hdev, ev->status);
2362 break;
2363
2364 case HCI_OP_SET_CONN_ENCRYPT:
2365 hci_cs_set_conn_encrypt(hdev, ev->status);
2366 break;
2367
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002368 case HCI_OP_REMOTE_NAME_REQ:
2369 hci_cs_remote_name_req(hdev, ev->status);
2370 break;
2371
Marcel Holtmann769be972008-07-14 20:13:49 +02002372 case HCI_OP_READ_REMOTE_FEATURES:
2373 hci_cs_read_remote_features(hdev, ev->status);
2374 break;
2375
2376 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2377 hci_cs_read_remote_ext_features(hdev, ev->status);
2378 break;
2379
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002380 case HCI_OP_SETUP_SYNC_CONN:
2381 hci_cs_setup_sync_conn(hdev, ev->status);
2382 break;
2383
2384 case HCI_OP_SNIFF_MODE:
2385 hci_cs_sniff_mode(hdev, ev->status);
2386 break;
2387
2388 case HCI_OP_EXIT_SNIFF_MODE:
2389 hci_cs_exit_sniff_mode(hdev, ev->status);
2390 break;
2391
Johan Hedberg8962ee72011-01-20 12:40:27 +02002392 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002393 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002394 break;
2395
Ville Tervofcd89c02011-02-10 22:38:47 -03002396 case HCI_OP_LE_CREATE_CONN:
2397 hci_cs_le_create_conn(hdev, ev->status);
2398 break;
2399
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002400 case HCI_OP_LE_START_ENC:
2401 hci_cs_le_start_enc(hdev, ev->status);
2402 break;
2403
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002404 default:
2405 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2406 break;
2407 }
2408
Ville Tervo6bd32322011-02-16 16:32:41 +02002409 if (ev->opcode != HCI_OP_NOP)
2410 del_timer(&hdev->cmd_timer);
2411
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002412 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002413 atomic_set(&hdev->cmd_cnt, 1);
2414 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002415 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002416 }
2417}
2418
2419static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2420{
2421 struct hci_ev_role_change *ev = (void *) skb->data;
2422 struct hci_conn *conn;
2423
2424 BT_DBG("%s status %d", hdev->name, ev->status);
2425
2426 hci_dev_lock(hdev);
2427
2428 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2429 if (conn) {
2430 if (!ev->status) {
2431 if (ev->role)
2432 conn->link_mode &= ~HCI_LM_MASTER;
2433 else
2434 conn->link_mode |= HCI_LM_MASTER;
2435 }
2436
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002437 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002438
2439 hci_role_switch_cfm(conn, ev->status, ev->role);
2440 }
2441
2442 hci_dev_unlock(hdev);
2443}
2444
Linus Torvalds1da177e2005-04-16 15:20:36 -07002445static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2446{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002447 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002448 int i;
2449
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002450 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2451 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2452 return;
2453 }
2454
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002455 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2456 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457 BT_DBG("%s bad parameters", hdev->name);
2458 return;
2459 }
2460
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002461 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2462
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002463 for (i = 0; i < ev->num_hndl; i++) {
2464 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002465 struct hci_conn *conn;
2466 __u16 handle, count;
2467
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002468 handle = __le16_to_cpu(info->handle);
2469 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002470
2471 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002472 if (!conn)
2473 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002474
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002475 conn->sent -= count;
2476
2477 switch (conn->type) {
2478 case ACL_LINK:
2479 hdev->acl_cnt += count;
2480 if (hdev->acl_cnt > hdev->acl_pkts)
2481 hdev->acl_cnt = hdev->acl_pkts;
2482 break;
2483
2484 case LE_LINK:
2485 if (hdev->le_pkts) {
2486 hdev->le_cnt += count;
2487 if (hdev->le_cnt > hdev->le_pkts)
2488 hdev->le_cnt = hdev->le_pkts;
2489 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002490 hdev->acl_cnt += count;
2491 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002492 hdev->acl_cnt = hdev->acl_pkts;
2493 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002494 break;
2495
2496 case SCO_LINK:
2497 hdev->sco_cnt += count;
2498 if (hdev->sco_cnt > hdev->sco_pkts)
2499 hdev->sco_cnt = hdev->sco_pkts;
2500 break;
2501
2502 default:
2503 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2504 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505 }
2506 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002507
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002508 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509}
2510
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002511static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2512 struct sk_buff *skb)
2513{
2514 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2515 int i;
2516
2517 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2518 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2519 return;
2520 }
2521
2522 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2523 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2524 BT_DBG("%s bad parameters", hdev->name);
2525 return;
2526 }
2527
2528 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2529 ev->num_hndl);
2530
2531 for (i = 0; i < ev->num_hndl; i++) {
2532 struct hci_comp_blocks_info *info = &ev->handles[i];
2533 struct hci_conn *conn;
2534 __u16 handle, block_count;
2535
2536 handle = __le16_to_cpu(info->handle);
2537 block_count = __le16_to_cpu(info->blocks);
2538
2539 conn = hci_conn_hash_lookup_handle(hdev, handle);
2540 if (!conn)
2541 continue;
2542
2543 conn->sent -= block_count;
2544
2545 switch (conn->type) {
2546 case ACL_LINK:
2547 hdev->block_cnt += block_count;
2548 if (hdev->block_cnt > hdev->num_blocks)
2549 hdev->block_cnt = hdev->num_blocks;
2550 break;
2551
2552 default:
2553 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2554 break;
2555 }
2556 }
2557
2558 queue_work(hdev->workqueue, &hdev->tx_work);
2559}
2560
Marcel Holtmann04837f62006-07-03 10:02:33 +02002561static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002563 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002564 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565
2566 BT_DBG("%s status %d", hdev->name, ev->status);
2567
2568 hci_dev_lock(hdev);
2569
Marcel Holtmann04837f62006-07-03 10:02:33 +02002570 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2571 if (conn) {
2572 conn->mode = ev->mode;
2573 conn->interval = __le16_to_cpu(ev->interval);
2574
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002575 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002576 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002577 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002578 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002579 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002580 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002581
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002582 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002583 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002584 }
2585
2586 hci_dev_unlock(hdev);
2587}
2588
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2590{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002591 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2592 struct hci_conn *conn;
2593
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002594 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002595
2596 hci_dev_lock(hdev);
2597
2598 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002599 if (!conn)
2600 goto unlock;
2601
2602 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002603 hci_conn_hold(conn);
2604 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2605 hci_conn_put(conn);
2606 }
2607
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002608 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002609 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2610 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002611 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002612 u8 secure;
2613
2614 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2615 secure = 1;
2616 else
2617 secure = 0;
2618
Johan Hedberg744cf192011-11-08 20:40:14 +02002619 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002620 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002621
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002622unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002623 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624}
2625
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2627{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002628 struct hci_ev_link_key_req *ev = (void *) skb->data;
2629 struct hci_cp_link_key_reply cp;
2630 struct hci_conn *conn;
2631 struct link_key *key;
2632
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002633 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002634
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002635 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002636 return;
2637
2638 hci_dev_lock(hdev);
2639
2640 key = hci_find_link_key(hdev, &ev->bdaddr);
2641 if (!key) {
2642 BT_DBG("%s link key not found for %s", hdev->name,
2643 batostr(&ev->bdaddr));
2644 goto not_found;
2645 }
2646
2647 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2648 batostr(&ev->bdaddr));
2649
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002650 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002651 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002652 BT_DBG("%s ignoring debug key", hdev->name);
2653 goto not_found;
2654 }
2655
2656 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002657 if (conn) {
2658 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2659 conn->auth_type != 0xff &&
2660 (conn->auth_type & 0x01)) {
2661 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2662 goto not_found;
2663 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002664
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002665 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2666 conn->pending_sec_level == BT_SECURITY_HIGH) {
2667 BT_DBG("%s ignoring key unauthenticated for high \
2668 security", hdev->name);
2669 goto not_found;
2670 }
2671
2672 conn->key_type = key->type;
2673 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002674 }
2675
2676 bacpy(&cp.bdaddr, &ev->bdaddr);
2677 memcpy(cp.link_key, key->val, 16);
2678
2679 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2680
2681 hci_dev_unlock(hdev);
2682
2683 return;
2684
2685not_found:
2686 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2687 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688}
2689
Linus Torvalds1da177e2005-04-16 15:20:36 -07002690static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2691{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002692 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2693 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002694 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002695
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002696 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002697
2698 hci_dev_lock(hdev);
2699
2700 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2701 if (conn) {
2702 hci_conn_hold(conn);
2703 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002704 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002705
2706 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2707 conn->key_type = ev->key_type;
2708
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002709 hci_conn_put(conn);
2710 }
2711
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002712 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002713 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002714 ev->key_type, pin_len);
2715
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002716 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002717}
2718
Marcel Holtmann04837f62006-07-03 10:02:33 +02002719static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2720{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002721 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002722 struct hci_conn *conn;
2723
2724 BT_DBG("%s status %d", hdev->name, ev->status);
2725
2726 hci_dev_lock(hdev);
2727
2728 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002729 if (conn && !ev->status) {
2730 struct inquiry_entry *ie;
2731
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002732 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2733 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002734 ie->data.clock_offset = ev->clock_offset;
2735 ie->timestamp = jiffies;
2736 }
2737 }
2738
2739 hci_dev_unlock(hdev);
2740}
2741
Marcel Holtmanna8746412008-07-14 20:13:46 +02002742static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2743{
2744 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2745 struct hci_conn *conn;
2746
2747 BT_DBG("%s status %d", hdev->name, ev->status);
2748
2749 hci_dev_lock(hdev);
2750
2751 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2752 if (conn && !ev->status)
2753 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2754
2755 hci_dev_unlock(hdev);
2756}
2757
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002758static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2759{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002760 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002761 struct inquiry_entry *ie;
2762
2763 BT_DBG("%s", hdev->name);
2764
2765 hci_dev_lock(hdev);
2766
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002767 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2768 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002769 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2770 ie->timestamp = jiffies;
2771 }
2772
2773 hci_dev_unlock(hdev);
2774}
2775
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002776static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2777{
2778 struct inquiry_data data;
2779 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg31754052012-01-04 13:39:52 +02002780 bool name_known;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002781
2782 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2783
2784 if (!num_rsp)
2785 return;
2786
2787 hci_dev_lock(hdev);
2788
2789 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002790 struct inquiry_info_with_rssi_and_pscan_mode *info;
2791 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002792
Johan Hedberge17acd42011-03-30 23:57:16 +03002793 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002794 bacpy(&data.bdaddr, &info->bdaddr);
2795 data.pscan_rep_mode = info->pscan_rep_mode;
2796 data.pscan_period_mode = info->pscan_period_mode;
2797 data.pscan_mode = info->pscan_mode;
2798 memcpy(data.dev_class, info->dev_class, 3);
2799 data.clock_offset = info->clock_offset;
2800 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002801 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002802
2803 name_known = hci_inquiry_cache_update(hdev, &data,
2804 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002805 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002806 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002807 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002808 }
2809 } else {
2810 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2811
Johan Hedberge17acd42011-03-30 23:57:16 +03002812 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002813 bacpy(&data.bdaddr, &info->bdaddr);
2814 data.pscan_rep_mode = info->pscan_rep_mode;
2815 data.pscan_period_mode = info->pscan_period_mode;
2816 data.pscan_mode = 0x00;
2817 memcpy(data.dev_class, info->dev_class, 3);
2818 data.clock_offset = info->clock_offset;
2819 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002820 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002821 name_known = hci_inquiry_cache_update(hdev, &data,
2822 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002823 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002824 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002825 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002826 }
2827 }
2828
2829 hci_dev_unlock(hdev);
2830}
2831
2832static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2833{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002834 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2835 struct hci_conn *conn;
2836
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002837 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002838
Marcel Holtmann41a96212008-07-14 20:13:48 +02002839 hci_dev_lock(hdev);
2840
2841 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002842 if (!conn)
2843 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002844
Johan Hedbergccd556f2010-11-10 17:11:51 +02002845 if (!ev->status && ev->page == 0x01) {
2846 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002847
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002848 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2849 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002850 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002851
Johan Hedberg58a681e2012-01-16 06:47:28 +02002852 if (ev->features[0] & 0x01)
2853 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002854 }
2855
Johan Hedbergccd556f2010-11-10 17:11:51 +02002856 if (conn->state != BT_CONFIG)
2857 goto unlock;
2858
Johan Hedberg127178d2010-11-18 22:22:29 +02002859 if (!ev->status) {
2860 struct hci_cp_remote_name_req cp;
2861 memset(&cp, 0, sizeof(cp));
2862 bacpy(&cp.bdaddr, &conn->dst);
2863 cp.pscan_rep_mode = 0x02;
2864 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002865 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2866 mgmt_device_connected(hdev, &conn->dst, conn->type,
2867 conn->dst_type, NULL, 0,
2868 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002869
Johan Hedberg127178d2010-11-18 22:22:29 +02002870 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002871 conn->state = BT_CONNECTED;
2872 hci_proto_connect_cfm(conn, ev->status);
2873 hci_conn_put(conn);
2874 }
2875
2876unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002877 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002878}
2879
2880static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2881{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002882 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2883 struct hci_conn *conn;
2884
2885 BT_DBG("%s status %d", hdev->name, ev->status);
2886
2887 hci_dev_lock(hdev);
2888
2889 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002890 if (!conn) {
2891 if (ev->link_type == ESCO_LINK)
2892 goto unlock;
2893
2894 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2895 if (!conn)
2896 goto unlock;
2897
2898 conn->type = SCO_LINK;
2899 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002900
Marcel Holtmann732547f2009-04-19 19:14:14 +02002901 switch (ev->status) {
2902 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002903 conn->handle = __le16_to_cpu(ev->handle);
2904 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002905
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002906 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002907 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002908 break;
2909
Stephen Coe705e5712010-02-16 11:29:44 -05002910 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002911 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002912 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002913 case 0x1f: /* Unspecified error */
2914 if (conn->out && conn->attempt < 2) {
2915 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2916 (hdev->esco_type & EDR_ESCO_MASK);
2917 hci_setup_sync(conn, conn->link->handle);
2918 goto unlock;
2919 }
2920 /* fall through */
2921
2922 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002923 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002924 break;
2925 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002926
2927 hci_proto_connect_cfm(conn, ev->status);
2928 if (ev->status)
2929 hci_conn_del(conn);
2930
2931unlock:
2932 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002933}
2934
2935static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2936{
2937 BT_DBG("%s", hdev->name);
2938}
2939
Marcel Holtmann04837f62006-07-03 10:02:33 +02002940static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2941{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002942 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002943
2944 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002945}
2946
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002947static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2948{
2949 struct inquiry_data data;
2950 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2951 int num_rsp = *((__u8 *) skb->data);
2952
2953 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2954
2955 if (!num_rsp)
2956 return;
2957
2958 hci_dev_lock(hdev);
2959
Johan Hedberge17acd42011-03-30 23:57:16 +03002960 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg561aafb2012-01-04 13:31:59 +02002961 bool name_known;
2962
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002963 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002964 data.pscan_rep_mode = info->pscan_rep_mode;
2965 data.pscan_period_mode = info->pscan_period_mode;
2966 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002967 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002968 data.clock_offset = info->clock_offset;
2969 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002970 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002971
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002972 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002973 name_known = eir_has_data_type(info->data,
2974 sizeof(info->data),
2975 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002976 else
2977 name_known = true;
2978
Johan Hedberg31754052012-01-04 13:39:52 +02002979 name_known = hci_inquiry_cache_update(hdev, &data, name_known);
Johan Hedberg48264f02011-11-09 13:58:58 +02002980 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002981 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002982 !name_known, info->data,
2983 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002984 }
2985
2986 hci_dev_unlock(hdev);
2987}
2988
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002989static inline u8 hci_get_auth_req(struct hci_conn *conn)
2990{
2991 /* If remote requests dedicated bonding follow that lead */
2992 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2993 /* If both remote and local IO capabilities allow MITM
2994 * protection then require it, otherwise don't */
2995 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2996 return 0x02;
2997 else
2998 return 0x03;
2999 }
3000
3001 /* If remote requests no-bonding follow that lead */
3002 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003003 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003004
3005 return conn->auth_type;
3006}
3007
Marcel Holtmann04936842008-07-14 20:13:48 +02003008static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3009{
3010 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3011 struct hci_conn *conn;
3012
3013 BT_DBG("%s", hdev->name);
3014
3015 hci_dev_lock(hdev);
3016
3017 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003018 if (!conn)
3019 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003020
Johan Hedberg03b555e2011-01-04 15:40:05 +02003021 hci_conn_hold(conn);
3022
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003023 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003024 goto unlock;
3025
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003026 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003027 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003028 struct hci_cp_io_capability_reply cp;
3029
3030 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303031 /* Change the IO capability from KeyboardDisplay
3032 * to DisplayYesNo as it is not supported by BT spec. */
3033 cp.capability = (conn->io_capability == 0x04) ?
3034 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003035 conn->auth_type = hci_get_auth_req(conn);
3036 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003037
Johan Hedberg58a681e2012-01-16 06:47:28 +02003038 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003039 hci_find_remote_oob_data(hdev, &conn->dst))
3040 cp.oob_data = 0x01;
3041 else
3042 cp.oob_data = 0x00;
3043
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003044 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3045 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003046 } else {
3047 struct hci_cp_io_capability_neg_reply cp;
3048
3049 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003050 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003051
3052 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3053 sizeof(cp), &cp);
3054 }
3055
3056unlock:
3057 hci_dev_unlock(hdev);
3058}
3059
3060static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3061{
3062 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3063 struct hci_conn *conn;
3064
3065 BT_DBG("%s", hdev->name);
3066
3067 hci_dev_lock(hdev);
3068
3069 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3070 if (!conn)
3071 goto unlock;
3072
Johan Hedberg03b555e2011-01-04 15:40:05 +02003073 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003074 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003075 if (ev->oob_data)
3076 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003077
3078unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003079 hci_dev_unlock(hdev);
3080}
3081
Johan Hedberga5c29682011-02-19 12:05:57 -03003082static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3083 struct sk_buff *skb)
3084{
3085 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003086 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003087 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003088
3089 BT_DBG("%s", hdev->name);
3090
3091 hci_dev_lock(hdev);
3092
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003093 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003094 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003095
Johan Hedberg7a828902011-04-28 11:28:53 -07003096 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3097 if (!conn)
3098 goto unlock;
3099
3100 loc_mitm = (conn->auth_type & 0x01);
3101 rem_mitm = (conn->remote_auth & 0x01);
3102
3103 /* If we require MITM but the remote device can't provide that
3104 * (it has NoInputNoOutput) then reject the confirmation
3105 * request. The only exception is when we're dedicated bonding
3106 * initiators (connect_cfm_cb set) since then we always have the MITM
3107 * bit set. */
3108 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3109 BT_DBG("Rejecting request: remote device can't provide MITM");
3110 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3111 sizeof(ev->bdaddr), &ev->bdaddr);
3112 goto unlock;
3113 }
3114
3115 /* If no side requires MITM protection; auto-accept */
3116 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3117 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003118
3119 /* If we're not the initiators request authorization to
3120 * proceed from user space (mgmt_user_confirm with
3121 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003122 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003123 BT_DBG("Confirming auto-accept as acceptor");
3124 confirm_hint = 1;
3125 goto confirm;
3126 }
3127
Johan Hedberg9f616562011-04-28 11:28:54 -07003128 BT_DBG("Auto-accept of user confirmation with %ums delay",
3129 hdev->auto_accept_delay);
3130
3131 if (hdev->auto_accept_delay > 0) {
3132 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3133 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3134 goto unlock;
3135 }
3136
Johan Hedberg7a828902011-04-28 11:28:53 -07003137 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3138 sizeof(ev->bdaddr), &ev->bdaddr);
3139 goto unlock;
3140 }
3141
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003142confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003143 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003144 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003145
3146unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003147 hci_dev_unlock(hdev);
3148}
3149
Brian Gix1143d452011-11-23 08:28:34 -08003150static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3151 struct sk_buff *skb)
3152{
3153 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3154
3155 BT_DBG("%s", hdev->name);
3156
3157 hci_dev_lock(hdev);
3158
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003159 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003160 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003161
3162 hci_dev_unlock(hdev);
3163}
3164
Marcel Holtmann04936842008-07-14 20:13:48 +02003165static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3166{
3167 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3168 struct hci_conn *conn;
3169
3170 BT_DBG("%s", hdev->name);
3171
3172 hci_dev_lock(hdev);
3173
3174 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003175 if (!conn)
3176 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003177
Johan Hedberg2a611692011-02-19 12:06:00 -03003178 /* To avoid duplicate auth_failed events to user space we check
3179 * the HCI_CONN_AUTH_PEND flag which will be set if we
3180 * initiated the authentication. A traditional auth_complete
3181 * event gets always produced as initiator and is also mapped to
3182 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003183 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003184 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3185 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003186
3187 hci_conn_put(conn);
3188
3189unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003190 hci_dev_unlock(hdev);
3191}
3192
Marcel Holtmann41a96212008-07-14 20:13:48 +02003193static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3194{
3195 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3196 struct inquiry_entry *ie;
3197
3198 BT_DBG("%s", hdev->name);
3199
3200 hci_dev_lock(hdev);
3201
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003202 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3203 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003204 ie->data.ssp_mode = (ev->features[0] & 0x01);
3205
3206 hci_dev_unlock(hdev);
3207}
3208
Szymon Janc2763eda2011-03-22 13:12:22 +01003209static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3210 struct sk_buff *skb)
3211{
3212 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3213 struct oob_data *data;
3214
3215 BT_DBG("%s", hdev->name);
3216
3217 hci_dev_lock(hdev);
3218
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003219 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003220 goto unlock;
3221
Szymon Janc2763eda2011-03-22 13:12:22 +01003222 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3223 if (data) {
3224 struct hci_cp_remote_oob_data_reply cp;
3225
3226 bacpy(&cp.bdaddr, &ev->bdaddr);
3227 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3228 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3229
3230 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3231 &cp);
3232 } else {
3233 struct hci_cp_remote_oob_data_neg_reply cp;
3234
3235 bacpy(&cp.bdaddr, &ev->bdaddr);
3236 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3237 &cp);
3238 }
3239
Szymon Jance1ba1f12011-04-06 13:01:59 +02003240unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003241 hci_dev_unlock(hdev);
3242}
3243
Ville Tervofcd89c02011-02-10 22:38:47 -03003244static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3245{
3246 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3247 struct hci_conn *conn;
3248
3249 BT_DBG("%s status %d", hdev->name, ev->status);
3250
3251 hci_dev_lock(hdev);
3252
3253 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003254 if (!conn) {
3255 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3256 if (!conn) {
3257 BT_ERR("No memory for new connection");
3258 hci_dev_unlock(hdev);
3259 return;
3260 }
Andre Guedes29b79882011-05-31 14:20:54 -03003261
3262 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003263 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003264
3265 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003266 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3267 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003268 hci_proto_connect_cfm(conn, ev->status);
3269 conn->state = BT_CLOSED;
3270 hci_conn_del(conn);
3271 goto unlock;
3272 }
3273
Johan Hedbergb644ba32012-01-17 21:48:47 +02003274 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3275 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3276 conn->dst_type, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003277
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003278 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003279 conn->handle = __le16_to_cpu(ev->handle);
3280 conn->state = BT_CONNECTED;
3281
3282 hci_conn_hold_device(conn);
3283 hci_conn_add_sysfs(conn);
3284
3285 hci_proto_connect_cfm(conn, ev->status);
3286
3287unlock:
3288 hci_dev_unlock(hdev);
3289}
3290
Andre Guedes9aa04c92011-05-26 16:23:51 -03003291static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3292 struct sk_buff *skb)
3293{
Andre Guedese95beb42011-09-26 20:48:35 -03003294 u8 num_reports = skb->data[0];
3295 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003296 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003297
3298 hci_dev_lock(hdev);
3299
Andre Guedese95beb42011-09-26 20:48:35 -03003300 while (num_reports--) {
3301 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003302
Andre Guedes9aa04c92011-05-26 16:23:51 -03003303 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003304
Andre Guedes3c9e9192012-01-10 18:20:50 -03003305 rssi = ev->data[ev->length];
3306 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3307 NULL, rssi, 0, ev->data, ev->length);
3308
Andre Guedese95beb42011-09-26 20:48:35 -03003309 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003310 }
3311
3312 hci_dev_unlock(hdev);
3313}
3314
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003315static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3316 struct sk_buff *skb)
3317{
3318 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3319 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003320 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003321 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003322 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003323
3324 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3325
3326 hci_dev_lock(hdev);
3327
3328 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003329 if (conn == NULL)
3330 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003331
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003332 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3333 if (ltk == NULL)
3334 goto not_found;
3335
3336 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003337 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003338
3339 if (ltk->authenticated)
3340 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003341
3342 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3343
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003344 if (ltk->type & HCI_SMP_STK) {
3345 list_del(&ltk->list);
3346 kfree(ltk);
3347 }
3348
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003349 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003350
3351 return;
3352
3353not_found:
3354 neg.handle = ev->handle;
3355 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3356 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003357}
3358
Ville Tervofcd89c02011-02-10 22:38:47 -03003359static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3360{
3361 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3362
3363 skb_pull(skb, sizeof(*le_ev));
3364
3365 switch (le_ev->subevent) {
3366 case HCI_EV_LE_CONN_COMPLETE:
3367 hci_le_conn_complete_evt(hdev, skb);
3368 break;
3369
Andre Guedes9aa04c92011-05-26 16:23:51 -03003370 case HCI_EV_LE_ADVERTISING_REPORT:
3371 hci_le_adv_report_evt(hdev, skb);
3372 break;
3373
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003374 case HCI_EV_LE_LTK_REQ:
3375 hci_le_ltk_request_evt(hdev, skb);
3376 break;
3377
Ville Tervofcd89c02011-02-10 22:38:47 -03003378 default:
3379 break;
3380 }
3381}
3382
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3384{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003385 struct hci_event_hdr *hdr = (void *) skb->data;
3386 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003387
3388 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3389
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003390 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003391 case HCI_EV_INQUIRY_COMPLETE:
3392 hci_inquiry_complete_evt(hdev, skb);
3393 break;
3394
3395 case HCI_EV_INQUIRY_RESULT:
3396 hci_inquiry_result_evt(hdev, skb);
3397 break;
3398
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003399 case HCI_EV_CONN_COMPLETE:
3400 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003401 break;
3402
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403 case HCI_EV_CONN_REQUEST:
3404 hci_conn_request_evt(hdev, skb);
3405 break;
3406
Linus Torvalds1da177e2005-04-16 15:20:36 -07003407 case HCI_EV_DISCONN_COMPLETE:
3408 hci_disconn_complete_evt(hdev, skb);
3409 break;
3410
Linus Torvalds1da177e2005-04-16 15:20:36 -07003411 case HCI_EV_AUTH_COMPLETE:
3412 hci_auth_complete_evt(hdev, skb);
3413 break;
3414
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003415 case HCI_EV_REMOTE_NAME:
3416 hci_remote_name_evt(hdev, skb);
3417 break;
3418
Linus Torvalds1da177e2005-04-16 15:20:36 -07003419 case HCI_EV_ENCRYPT_CHANGE:
3420 hci_encrypt_change_evt(hdev, skb);
3421 break;
3422
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003423 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3424 hci_change_link_key_complete_evt(hdev, skb);
3425 break;
3426
3427 case HCI_EV_REMOTE_FEATURES:
3428 hci_remote_features_evt(hdev, skb);
3429 break;
3430
3431 case HCI_EV_REMOTE_VERSION:
3432 hci_remote_version_evt(hdev, skb);
3433 break;
3434
3435 case HCI_EV_QOS_SETUP_COMPLETE:
3436 hci_qos_setup_complete_evt(hdev, skb);
3437 break;
3438
3439 case HCI_EV_CMD_COMPLETE:
3440 hci_cmd_complete_evt(hdev, skb);
3441 break;
3442
3443 case HCI_EV_CMD_STATUS:
3444 hci_cmd_status_evt(hdev, skb);
3445 break;
3446
3447 case HCI_EV_ROLE_CHANGE:
3448 hci_role_change_evt(hdev, skb);
3449 break;
3450
3451 case HCI_EV_NUM_COMP_PKTS:
3452 hci_num_comp_pkts_evt(hdev, skb);
3453 break;
3454
3455 case HCI_EV_MODE_CHANGE:
3456 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003457 break;
3458
3459 case HCI_EV_PIN_CODE_REQ:
3460 hci_pin_code_request_evt(hdev, skb);
3461 break;
3462
3463 case HCI_EV_LINK_KEY_REQ:
3464 hci_link_key_request_evt(hdev, skb);
3465 break;
3466
3467 case HCI_EV_LINK_KEY_NOTIFY:
3468 hci_link_key_notify_evt(hdev, skb);
3469 break;
3470
3471 case HCI_EV_CLOCK_OFFSET:
3472 hci_clock_offset_evt(hdev, skb);
3473 break;
3474
Marcel Holtmanna8746412008-07-14 20:13:46 +02003475 case HCI_EV_PKT_TYPE_CHANGE:
3476 hci_pkt_type_change_evt(hdev, skb);
3477 break;
3478
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003479 case HCI_EV_PSCAN_REP_MODE:
3480 hci_pscan_rep_mode_evt(hdev, skb);
3481 break;
3482
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003483 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3484 hci_inquiry_result_with_rssi_evt(hdev, skb);
3485 break;
3486
3487 case HCI_EV_REMOTE_EXT_FEATURES:
3488 hci_remote_ext_features_evt(hdev, skb);
3489 break;
3490
3491 case HCI_EV_SYNC_CONN_COMPLETE:
3492 hci_sync_conn_complete_evt(hdev, skb);
3493 break;
3494
3495 case HCI_EV_SYNC_CONN_CHANGED:
3496 hci_sync_conn_changed_evt(hdev, skb);
3497 break;
3498
Marcel Holtmann04837f62006-07-03 10:02:33 +02003499 case HCI_EV_SNIFF_SUBRATE:
3500 hci_sniff_subrate_evt(hdev, skb);
3501 break;
3502
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003503 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3504 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003505 break;
3506
Marcel Holtmann04936842008-07-14 20:13:48 +02003507 case HCI_EV_IO_CAPA_REQUEST:
3508 hci_io_capa_request_evt(hdev, skb);
3509 break;
3510
Johan Hedberg03b555e2011-01-04 15:40:05 +02003511 case HCI_EV_IO_CAPA_REPLY:
3512 hci_io_capa_reply_evt(hdev, skb);
3513 break;
3514
Johan Hedberga5c29682011-02-19 12:05:57 -03003515 case HCI_EV_USER_CONFIRM_REQUEST:
3516 hci_user_confirm_request_evt(hdev, skb);
3517 break;
3518
Brian Gix1143d452011-11-23 08:28:34 -08003519 case HCI_EV_USER_PASSKEY_REQUEST:
3520 hci_user_passkey_request_evt(hdev, skb);
3521 break;
3522
Marcel Holtmann04936842008-07-14 20:13:48 +02003523 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3524 hci_simple_pair_complete_evt(hdev, skb);
3525 break;
3526
Marcel Holtmann41a96212008-07-14 20:13:48 +02003527 case HCI_EV_REMOTE_HOST_FEATURES:
3528 hci_remote_host_features_evt(hdev, skb);
3529 break;
3530
Ville Tervofcd89c02011-02-10 22:38:47 -03003531 case HCI_EV_LE_META:
3532 hci_le_meta_evt(hdev, skb);
3533 break;
3534
Szymon Janc2763eda2011-03-22 13:12:22 +01003535 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3536 hci_remote_oob_data_request_evt(hdev, skb);
3537 break;
3538
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003539 case HCI_EV_NUM_COMP_BLOCKS:
3540 hci_num_comp_blocks_evt(hdev, skb);
3541 break;
3542
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003543 default:
3544 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003545 break;
3546 }
3547
3548 kfree_skb(skb);
3549 hdev->stat.evt_rx++;
3550}