blob: 240dc1640c04b2f54554abd012794cba2ad396f8 [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_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
424{
425 __u8 status = *((__u8 *) skb->data);
426 void *sent;
427
428 BT_DBG("%s status 0x%x", hdev->name, status);
429
Marcel Holtmann333140b2008-07-14 20:13:48 +0200430 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
431 if (!sent)
432 return;
433
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200434 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200435 mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status);
436 else if (!status) {
437 if (*((u8 *) sent))
438 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
439 else
440 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
441 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200442}
443
Johan Hedbergd5859e22011-01-25 01:19:58 +0200444static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
445{
446 if (hdev->features[6] & LMP_EXT_INQ)
447 return 2;
448
449 if (hdev->features[3] & LMP_RSSI_INQ)
450 return 1;
451
452 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
453 hdev->lmp_subver == 0x0757)
454 return 1;
455
456 if (hdev->manufacturer == 15) {
457 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
458 return 1;
459 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
460 return 1;
461 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
462 return 1;
463 }
464
465 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
466 hdev->lmp_subver == 0x1805)
467 return 1;
468
469 return 0;
470}
471
472static void hci_setup_inquiry_mode(struct hci_dev *hdev)
473{
474 u8 mode;
475
476 mode = hci_get_inquiry_mode(hdev);
477
478 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
479}
480
481static void hci_setup_event_mask(struct hci_dev *hdev)
482{
483 /* The second byte is 0xff instead of 0x9f (two reserved bits
484 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
485 * command otherwise */
486 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
487
Ville Tervo6de6c182011-05-27 11:16:21 +0300488 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
489 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200490 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300491 return;
492
493 events[4] |= 0x01; /* Flow Specification Complete */
494 events[4] |= 0x02; /* Inquiry Result with RSSI */
495 events[4] |= 0x04; /* Read Remote Extended Features Complete */
496 events[5] |= 0x08; /* Synchronous Connection Complete */
497 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200498
499 if (hdev->features[3] & LMP_RSSI_INQ)
500 events[4] |= 0x04; /* Inquiry Result with RSSI */
501
502 if (hdev->features[5] & LMP_SNIFF_SUBR)
503 events[5] |= 0x20; /* Sniff Subrating */
504
505 if (hdev->features[5] & LMP_PAUSE_ENC)
506 events[5] |= 0x80; /* Encryption Key Refresh Complete */
507
508 if (hdev->features[6] & LMP_EXT_INQ)
509 events[5] |= 0x40; /* Extended Inquiry Result */
510
511 if (hdev->features[6] & LMP_NO_FLUSH)
512 events[7] |= 0x01; /* Enhanced Flush Complete */
513
514 if (hdev->features[7] & LMP_LSTO)
515 events[6] |= 0x80; /* Link Supervision Timeout Changed */
516
517 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
518 events[6] |= 0x01; /* IO Capability Request */
519 events[6] |= 0x02; /* IO Capability Response */
520 events[6] |= 0x04; /* User Confirmation Request */
521 events[6] |= 0x08; /* User Passkey Request */
522 events[6] |= 0x10; /* Remote OOB Data Request */
523 events[6] |= 0x20; /* Simple Pairing Complete */
524 events[7] |= 0x04; /* User Passkey Notification */
525 events[7] |= 0x08; /* Keypress Notification */
526 events[7] |= 0x10; /* Remote Host Supported
527 * Features Notification */
528 }
529
530 if (hdev->features[4] & LMP_LE)
531 events[7] |= 0x20; /* LE Meta-Event */
532
533 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
534}
535
Andre Guedese6100a22011-06-30 19:20:54 -0300536static void hci_set_le_support(struct hci_dev *hdev)
537{
538 struct hci_cp_write_le_host_supported cp;
539
540 memset(&cp, 0, sizeof(cp));
541
542 if (enable_le) {
543 cp.le = 1;
544 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
545 }
546
547 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
548}
549
Johan Hedbergd5859e22011-01-25 01:19:58 +0200550static void hci_setup(struct hci_dev *hdev)
551{
Andrei Emeltchenkoe61ef492011-12-19 16:31:27 +0200552 if (hdev->dev_type != HCI_BREDR)
553 return;
554
Johan Hedbergd5859e22011-01-25 01:19:58 +0200555 hci_setup_event_mask(hdev);
556
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200557 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200558 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
559
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200560 if (hdev->features[6] & LMP_SIMPLE_PAIR &&
561 test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
Johan Hedbergd5859e22011-01-25 01:19:58 +0200562 u8 mode = 0x01;
563 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
564 }
565
566 if (hdev->features[3] & LMP_RSSI_INQ)
567 hci_setup_inquiry_mode(hdev);
568
569 if (hdev->features[7] & LMP_INQ_TX_PWR)
570 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300571
572 if (hdev->features[7] & LMP_EXTFEATURES) {
573 struct hci_cp_read_local_ext_features cp;
574
575 cp.page = 0x01;
576 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
577 sizeof(cp), &cp);
578 }
Andre Guedese6100a22011-06-30 19:20:54 -0300579
Johan Hedberg47990ea2012-02-22 11:58:37 +0200580 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
581 u8 enable = 1;
582 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE,
583 sizeof(enable), &enable);
584 }
585
Andre Guedese6100a22011-06-30 19:20:54 -0300586 if (hdev->features[4] & LMP_LE)
587 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200588}
589
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200590static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
591{
592 struct hci_rp_read_local_version *rp = (void *) skb->data;
593
594 BT_DBG("%s status 0x%x", hdev->name, rp->status);
595
596 if (rp->status)
597 return;
598
599 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200600 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200601 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200602 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200603 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200604
605 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
606 hdev->manufacturer,
607 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200608
609 if (test_bit(HCI_INIT, &hdev->flags))
610 hci_setup(hdev);
611}
612
613static void hci_setup_link_policy(struct hci_dev *hdev)
614{
615 u16 link_policy = 0;
616
617 if (hdev->features[0] & LMP_RSWITCH)
618 link_policy |= HCI_LP_RSWITCH;
619 if (hdev->features[0] & LMP_HOLD)
620 link_policy |= HCI_LP_HOLD;
621 if (hdev->features[0] & LMP_SNIFF)
622 link_policy |= HCI_LP_SNIFF;
623 if (hdev->features[1] & LMP_PARK)
624 link_policy |= HCI_LP_PARK;
625
626 link_policy = cpu_to_le16(link_policy);
627 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
628 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200629}
630
631static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
632{
633 struct hci_rp_read_local_commands *rp = (void *) skb->data;
634
635 BT_DBG("%s status 0x%x", hdev->name, rp->status);
636
637 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200638 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200639
640 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200641
642 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
643 hci_setup_link_policy(hdev);
644
645done:
646 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200647}
648
649static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
650{
651 struct hci_rp_read_local_features *rp = (void *) skb->data;
652
653 BT_DBG("%s status 0x%x", hdev->name, rp->status);
654
655 if (rp->status)
656 return;
657
658 memcpy(hdev->features, rp->features, 8);
659
660 /* Adjust default settings according to features
661 * supported by device. */
662
663 if (hdev->features[0] & LMP_3SLOT)
664 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
665
666 if (hdev->features[0] & LMP_5SLOT)
667 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
668
669 if (hdev->features[1] & LMP_HV2) {
670 hdev->pkt_type |= (HCI_HV2);
671 hdev->esco_type |= (ESCO_HV2);
672 }
673
674 if (hdev->features[1] & LMP_HV3) {
675 hdev->pkt_type |= (HCI_HV3);
676 hdev->esco_type |= (ESCO_HV3);
677 }
678
679 if (hdev->features[3] & LMP_ESCO)
680 hdev->esco_type |= (ESCO_EV3);
681
682 if (hdev->features[4] & LMP_EV4)
683 hdev->esco_type |= (ESCO_EV4);
684
685 if (hdev->features[4] & LMP_EV5)
686 hdev->esco_type |= (ESCO_EV5);
687
Marcel Holtmannefc76882009-02-06 09:13:37 +0100688 if (hdev->features[5] & LMP_EDR_ESCO_2M)
689 hdev->esco_type |= (ESCO_2EV3);
690
691 if (hdev->features[5] & LMP_EDR_ESCO_3M)
692 hdev->esco_type |= (ESCO_3EV3);
693
694 if (hdev->features[5] & LMP_EDR_3S_ESCO)
695 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
696
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200697 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
698 hdev->features[0], hdev->features[1],
699 hdev->features[2], hdev->features[3],
700 hdev->features[4], hdev->features[5],
701 hdev->features[6], hdev->features[7]);
702}
703
Andre Guedes971e3a42011-06-30 19:20:52 -0300704static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
705 struct sk_buff *skb)
706{
707 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
708
709 BT_DBG("%s status 0x%x", hdev->name, rp->status);
710
711 if (rp->status)
712 return;
713
Andre Guedesb5b32b62011-12-30 10:34:04 -0300714 switch (rp->page) {
715 case 0:
716 memcpy(hdev->features, rp->features, 8);
717 break;
718 case 1:
719 memcpy(hdev->host_features, rp->features, 8);
720 break;
721 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300722
723 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
724}
725
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200726static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
727 struct sk_buff *skb)
728{
729 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
730
731 BT_DBG("%s status 0x%x", hdev->name, rp->status);
732
733 if (rp->status)
734 return;
735
736 hdev->flow_ctl_mode = rp->mode;
737
738 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
739}
740
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200741static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
742{
743 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
744
745 BT_DBG("%s status 0x%x", hdev->name, rp->status);
746
747 if (rp->status)
748 return;
749
750 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
751 hdev->sco_mtu = rp->sco_mtu;
752 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
753 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
754
755 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
756 hdev->sco_mtu = 64;
757 hdev->sco_pkts = 8;
758 }
759
760 hdev->acl_cnt = hdev->acl_pkts;
761 hdev->sco_cnt = hdev->sco_pkts;
762
763 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
764 hdev->acl_mtu, hdev->acl_pkts,
765 hdev->sco_mtu, hdev->sco_pkts);
766}
767
768static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
769{
770 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
771
772 BT_DBG("%s status 0x%x", hdev->name, rp->status);
773
774 if (!rp->status)
775 bacpy(&hdev->bdaddr, &rp->bdaddr);
776
Johan Hedberg23bb5762010-12-21 23:01:27 +0200777 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
778}
779
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200780static void hci_cc_read_data_block_size(struct hci_dev *hdev,
781 struct sk_buff *skb)
782{
783 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
784
785 BT_DBG("%s status 0x%x", hdev->name, rp->status);
786
787 if (rp->status)
788 return;
789
790 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
791 hdev->block_len = __le16_to_cpu(rp->block_len);
792 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
793
794 hdev->block_cnt = hdev->num_blocks;
795
796 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
797 hdev->block_cnt, hdev->block_len);
798
799 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
800}
801
Johan Hedberg23bb5762010-12-21 23:01:27 +0200802static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
803{
804 __u8 status = *((__u8 *) skb->data);
805
806 BT_DBG("%s status 0x%x", hdev->name, status);
807
808 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200809}
810
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300811static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
812 struct sk_buff *skb)
813{
814 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
815
816 BT_DBG("%s status 0x%x", hdev->name, rp->status);
817
818 if (rp->status)
819 return;
820
821 hdev->amp_status = rp->amp_status;
822 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
823 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
824 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
825 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
826 hdev->amp_type = rp->amp_type;
827 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
828 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
829 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
830 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
831
832 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
833}
834
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200835static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
836 struct sk_buff *skb)
837{
838 __u8 status = *((__u8 *) skb->data);
839
840 BT_DBG("%s status 0x%x", hdev->name, status);
841
842 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
843}
844
Johan Hedbergd5859e22011-01-25 01:19:58 +0200845static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
846{
847 __u8 status = *((__u8 *) skb->data);
848
849 BT_DBG("%s status 0x%x", hdev->name, status);
850
851 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
852}
853
854static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
855 struct sk_buff *skb)
856{
857 __u8 status = *((__u8 *) skb->data);
858
859 BT_DBG("%s status 0x%x", hdev->name, status);
860
861 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
862}
863
864static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
865 struct sk_buff *skb)
866{
867 __u8 status = *((__u8 *) skb->data);
868
869 BT_DBG("%s status 0x%x", hdev->name, status);
870
871 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
872}
873
874static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
875{
876 __u8 status = *((__u8 *) skb->data);
877
878 BT_DBG("%s status 0x%x", hdev->name, status);
879
880 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
881}
882
Johan Hedberg980e1a52011-01-22 06:10:07 +0200883static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
884{
885 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
886 struct hci_cp_pin_code_reply *cp;
887 struct hci_conn *conn;
888
889 BT_DBG("%s status 0x%x", hdev->name, rp->status);
890
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200891 hci_dev_lock(hdev);
892
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200893 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200894 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200895
896 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200897 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200898
899 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
900 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200901 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200902
903 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
904 if (conn)
905 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200906
907unlock:
908 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200909}
910
911static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
912{
913 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
914
915 BT_DBG("%s status 0x%x", hdev->name, rp->status);
916
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200917 hci_dev_lock(hdev);
918
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200919 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200920 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200921 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200922
923 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200924}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200925
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300926static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
927 struct sk_buff *skb)
928{
929 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
930
931 BT_DBG("%s status 0x%x", hdev->name, rp->status);
932
933 if (rp->status)
934 return;
935
936 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
937 hdev->le_pkts = rp->le_max_pkt;
938
939 hdev->le_cnt = hdev->le_pkts;
940
941 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
942
943 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
944}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200945
Johan Hedberga5c29682011-02-19 12:05:57 -0300946static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
947{
948 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
949
950 BT_DBG("%s status 0x%x", hdev->name, rp->status);
951
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200952 hci_dev_lock(hdev);
953
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200954 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200955 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
956 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200957
958 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300959}
960
961static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
962 struct sk_buff *skb)
963{
964 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
965
966 BT_DBG("%s status 0x%x", hdev->name, rp->status);
967
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200968 hci_dev_lock(hdev);
969
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200970 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200971 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200972 ACL_LINK, 0,
Johan Hedberga5c29682011-02-19 12:05:57 -0300973 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200974
975 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300976}
977
Brian Gix1143d452011-11-23 08:28:34 -0800978static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
979{
980 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
981
982 BT_DBG("%s status 0x%x", hdev->name, rp->status);
983
984 hci_dev_lock(hdev);
985
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200986 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200987 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
988 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800989
990 hci_dev_unlock(hdev);
991}
992
993static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
994 struct sk_buff *skb)
995{
996 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
997
998 BT_DBG("%s status 0x%x", hdev->name, rp->status);
999
1000 hci_dev_lock(hdev);
1001
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001002 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001003 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001004 ACL_LINK, 0,
Brian Gix1143d452011-11-23 08:28:34 -08001005 rp->status);
1006
1007 hci_dev_unlock(hdev);
1008}
1009
Szymon Jancc35938b2011-03-22 13:12:21 +01001010static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1011 struct sk_buff *skb)
1012{
1013 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1014
1015 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1016
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001017 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001018 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001019 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001020 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001021}
1022
Andre Guedes07f7fa52011-12-02 21:13:31 +09001023static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1024{
1025 __u8 status = *((__u8 *) skb->data);
1026
1027 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001028
1029 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001030
1031 if (status) {
1032 hci_dev_lock(hdev);
1033 mgmt_start_discovery_failed(hdev, status);
1034 hci_dev_unlock(hdev);
1035 return;
1036 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001037}
1038
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001039static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1040 struct sk_buff *skb)
1041{
1042 struct hci_cp_le_set_scan_enable *cp;
1043 __u8 status = *((__u8 *) skb->data);
1044
1045 BT_DBG("%s status 0x%x", hdev->name, status);
1046
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001047 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1048 if (!cp)
1049 return;
1050
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001051 switch (cp->enable) {
1052 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001053 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1054
Andre Guedes3fd24152012-02-03 17:48:01 -03001055 if (status) {
1056 hci_dev_lock(hdev);
1057 mgmt_start_discovery_failed(hdev, status);
1058 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001059 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001060 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001061
Andre Guedesd23264a2011-11-25 20:53:38 -03001062 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1063
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001064 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001065
1066 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001067 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001068 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001069 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001070 break;
1071
1072 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001073 if (status)
1074 return;
1075
Andre Guedesd23264a2011-11-25 20:53:38 -03001076 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1077
Andre Guedesd0843292012-01-02 19:18:11 -03001078 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001079
1080 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1081 mgmt_interleaved_discovery(hdev);
1082 } else {
1083 hci_dev_lock(hdev);
1084 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1085 hci_dev_unlock(hdev);
1086 }
1087
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001088 break;
1089
1090 default:
1091 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1092 break;
Andre Guedes35815082011-05-26 16:23:53 -03001093 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001094}
1095
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001096static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1097{
1098 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1099
1100 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1101
1102 if (rp->status)
1103 return;
1104
1105 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1106}
1107
1108static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1109{
1110 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1111
1112 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1113
1114 if (rp->status)
1115 return;
1116
1117 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1118}
1119
Andre Guedesf9b49302011-06-30 19:20:53 -03001120static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1121 struct sk_buff *skb)
1122{
1123 struct hci_cp_read_local_ext_features cp;
1124 __u8 status = *((__u8 *) skb->data);
1125
1126 BT_DBG("%s status 0x%x", hdev->name, status);
1127
1128 if (status)
1129 return;
1130
1131 cp.page = 0x01;
1132 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1133}
1134
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001135static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1136{
1137 BT_DBG("%s status 0x%x", hdev->name, status);
1138
1139 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001140 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001141 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001142 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001143 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001144 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001145 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001146 return;
1147 }
1148
Andre Guedes89352e72011-11-04 14:16:53 -03001149 set_bit(HCI_INQUIRY, &hdev->flags);
1150
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001151 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001152 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001153 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001154}
1155
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1157{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001158 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001161 BT_DBG("%s status 0x%x", hdev->name, status);
1162
1163 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 if (!cp)
1165 return;
1166
1167 hci_dev_lock(hdev);
1168
1169 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1170
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001171 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172
1173 if (status) {
1174 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001175 if (status != 0x0c || conn->attempt > 2) {
1176 conn->state = BT_CLOSED;
1177 hci_proto_connect_cfm(conn, status);
1178 hci_conn_del(conn);
1179 } else
1180 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 }
1182 } else {
1183 if (!conn) {
1184 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1185 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001186 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187 conn->link_mode |= HCI_LM_MASTER;
1188 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001189 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 }
1191 }
1192
1193 hci_dev_unlock(hdev);
1194}
1195
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001196static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001198 struct hci_cp_add_sco *cp;
1199 struct hci_conn *acl, *sco;
1200 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001202 BT_DBG("%s status 0x%x", hdev->name, status);
1203
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001204 if (!status)
1205 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001207 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1208 if (!cp)
1209 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001211 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001213 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001214
1215 hci_dev_lock(hdev);
1216
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001217 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001218 if (acl) {
1219 sco = acl->link;
1220 if (sco) {
1221 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001222
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001223 hci_proto_connect_cfm(sco, status);
1224 hci_conn_del(sco);
1225 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001226 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001227
1228 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229}
1230
Marcel Holtmannf8558552008-07-14 20:13:49 +02001231static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1232{
1233 struct hci_cp_auth_requested *cp;
1234 struct hci_conn *conn;
1235
1236 BT_DBG("%s status 0x%x", hdev->name, status);
1237
1238 if (!status)
1239 return;
1240
1241 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1242 if (!cp)
1243 return;
1244
1245 hci_dev_lock(hdev);
1246
1247 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1248 if (conn) {
1249 if (conn->state == BT_CONFIG) {
1250 hci_proto_connect_cfm(conn, status);
1251 hci_conn_put(conn);
1252 }
1253 }
1254
1255 hci_dev_unlock(hdev);
1256}
1257
1258static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1259{
1260 struct hci_cp_set_conn_encrypt *cp;
1261 struct hci_conn *conn;
1262
1263 BT_DBG("%s status 0x%x", hdev->name, status);
1264
1265 if (!status)
1266 return;
1267
1268 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1269 if (!cp)
1270 return;
1271
1272 hci_dev_lock(hdev);
1273
1274 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1275 if (conn) {
1276 if (conn->state == BT_CONFIG) {
1277 hci_proto_connect_cfm(conn, status);
1278 hci_conn_put(conn);
1279 }
1280 }
1281
1282 hci_dev_unlock(hdev);
1283}
1284
Johan Hedberg127178d2010-11-18 22:22:29 +02001285static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001286 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001287{
Johan Hedberg392599b2010-11-18 22:22:28 +02001288 if (conn->state != BT_CONFIG || !conn->out)
1289 return 0;
1290
Johan Hedberg765c2a92011-01-19 12:06:52 +05301291 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001292 return 0;
1293
1294 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001295 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001296 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001297 conn->pending_sec_level != BT_SECURITY_HIGH &&
1298 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001299 return 0;
1300
Johan Hedberg392599b2010-11-18 22:22:28 +02001301 return 1;
1302}
1303
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001304static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1305{
1306 struct hci_cp_remote_name_req cp;
1307
1308 memset(&cp, 0, sizeof(cp));
1309
1310 bacpy(&cp.bdaddr, &e->data.bdaddr);
1311 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1312 cp.pscan_mode = e->data.pscan_mode;
1313 cp.clock_offset = e->data.clock_offset;
1314
1315 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1316}
1317
Johan Hedbergb644ba32012-01-17 21:48:47 +02001318static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001319{
1320 struct discovery_state *discov = &hdev->discovery;
1321 struct inquiry_entry *e;
1322
Johan Hedbergb644ba32012-01-17 21:48:47 +02001323 if (list_empty(&discov->resolve))
1324 return false;
1325
1326 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1327 if (hci_resolve_name(hdev, e) == 0) {
1328 e->name_state = NAME_PENDING;
1329 return true;
1330 }
1331
1332 return false;
1333}
1334
1335static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1336 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1337{
1338 struct discovery_state *discov = &hdev->discovery;
1339 struct inquiry_entry *e;
1340
1341 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1342 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
1343 name, name_len, conn->dev_class);
1344
1345 if (discov->state == DISCOVERY_STOPPED)
1346 return;
1347
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001348 if (discov->state == DISCOVERY_STOPPING)
1349 goto discov_complete;
1350
1351 if (discov->state != DISCOVERY_RESOLVING)
1352 return;
1353
1354 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1355 if (e) {
1356 e->name_state = NAME_KNOWN;
1357 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001358 if (name)
1359 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1360 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001361 }
1362
Johan Hedbergb644ba32012-01-17 21:48:47 +02001363 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001364 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001365
1366discov_complete:
1367 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1368}
1369
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001370static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1371{
Johan Hedberg127178d2010-11-18 22:22:29 +02001372 struct hci_cp_remote_name_req *cp;
1373 struct hci_conn *conn;
1374
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001375 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001376
1377 /* If successful wait for the name req complete event before
1378 * checking for the need to do authentication */
1379 if (!status)
1380 return;
1381
1382 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1383 if (!cp)
1384 return;
1385
1386 hci_dev_lock(hdev);
1387
1388 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001389
1390 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1391 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1392
Johan Hedberg79c6c702011-04-28 11:28:55 -07001393 if (!conn)
1394 goto unlock;
1395
1396 if (!hci_outgoing_auth_needed(hdev, conn))
1397 goto unlock;
1398
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001399 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001400 struct hci_cp_auth_requested cp;
1401 cp.handle = __cpu_to_le16(conn->handle);
1402 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1403 }
1404
Johan Hedberg79c6c702011-04-28 11:28:55 -07001405unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001406 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001407}
1408
Marcel Holtmann769be972008-07-14 20:13:49 +02001409static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1410{
1411 struct hci_cp_read_remote_features *cp;
1412 struct hci_conn *conn;
1413
1414 BT_DBG("%s status 0x%x", hdev->name, status);
1415
1416 if (!status)
1417 return;
1418
1419 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1420 if (!cp)
1421 return;
1422
1423 hci_dev_lock(hdev);
1424
1425 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1426 if (conn) {
1427 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001428 hci_proto_connect_cfm(conn, status);
1429 hci_conn_put(conn);
1430 }
1431 }
1432
1433 hci_dev_unlock(hdev);
1434}
1435
1436static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1437{
1438 struct hci_cp_read_remote_ext_features *cp;
1439 struct hci_conn *conn;
1440
1441 BT_DBG("%s status 0x%x", hdev->name, status);
1442
1443 if (!status)
1444 return;
1445
1446 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1447 if (!cp)
1448 return;
1449
1450 hci_dev_lock(hdev);
1451
1452 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1453 if (conn) {
1454 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001455 hci_proto_connect_cfm(conn, status);
1456 hci_conn_put(conn);
1457 }
1458 }
1459
1460 hci_dev_unlock(hdev);
1461}
1462
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001463static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1464{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001465 struct hci_cp_setup_sync_conn *cp;
1466 struct hci_conn *acl, *sco;
1467 __u16 handle;
1468
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001469 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001470
1471 if (!status)
1472 return;
1473
1474 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1475 if (!cp)
1476 return;
1477
1478 handle = __le16_to_cpu(cp->handle);
1479
1480 BT_DBG("%s handle %d", hdev->name, handle);
1481
1482 hci_dev_lock(hdev);
1483
1484 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001485 if (acl) {
1486 sco = acl->link;
1487 if (sco) {
1488 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001489
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001490 hci_proto_connect_cfm(sco, status);
1491 hci_conn_del(sco);
1492 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001493 }
1494
1495 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001496}
1497
1498static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1499{
1500 struct hci_cp_sniff_mode *cp;
1501 struct hci_conn *conn;
1502
1503 BT_DBG("%s status 0x%x", hdev->name, status);
1504
1505 if (!status)
1506 return;
1507
1508 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1509 if (!cp)
1510 return;
1511
1512 hci_dev_lock(hdev);
1513
1514 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001515 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001516 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001517
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001518 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001519 hci_sco_setup(conn, status);
1520 }
1521
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001522 hci_dev_unlock(hdev);
1523}
1524
1525static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1526{
1527 struct hci_cp_exit_sniff_mode *cp;
1528 struct hci_conn *conn;
1529
1530 BT_DBG("%s status 0x%x", hdev->name, status);
1531
1532 if (!status)
1533 return;
1534
1535 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1536 if (!cp)
1537 return;
1538
1539 hci_dev_lock(hdev);
1540
1541 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001542 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001543 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001544
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001545 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001546 hci_sco_setup(conn, status);
1547 }
1548
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001549 hci_dev_unlock(hdev);
1550}
1551
Johan Hedberg88c3df12012-02-09 14:27:38 +02001552static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1553{
1554 struct hci_cp_disconnect *cp;
1555 struct hci_conn *conn;
1556
1557 if (!status)
1558 return;
1559
1560 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1561 if (!cp)
1562 return;
1563
1564 hci_dev_lock(hdev);
1565
1566 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1567 if (conn)
1568 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1569 conn->dst_type, status);
1570
1571 hci_dev_unlock(hdev);
1572}
1573
Ville Tervofcd89c02011-02-10 22:38:47 -03001574static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1575{
1576 struct hci_cp_le_create_conn *cp;
1577 struct hci_conn *conn;
1578
1579 BT_DBG("%s status 0x%x", hdev->name, status);
1580
1581 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1582 if (!cp)
1583 return;
1584
1585 hci_dev_lock(hdev);
1586
1587 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1588
1589 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1590 conn);
1591
1592 if (status) {
1593 if (conn && conn->state == BT_CONNECT) {
1594 conn->state = BT_CLOSED;
1595 hci_proto_connect_cfm(conn, status);
1596 hci_conn_del(conn);
1597 }
1598 } else {
1599 if (!conn) {
1600 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001601 if (conn) {
1602 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001603 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001604 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001605 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001606 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001607 }
1608 }
1609
1610 hci_dev_unlock(hdev);
1611}
1612
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001613static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1614{
1615 BT_DBG("%s status 0x%x", hdev->name, status);
1616}
1617
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001618static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1619{
1620 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001621 struct discovery_state *discov = &hdev->discovery;
1622 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001623
1624 BT_DBG("%s status %d", hdev->name, status);
1625
Johan Hedberg23bb5762010-12-21 23:01:27 +02001626 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001627
1628 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001629
1630 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1631 return;
1632
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001633 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001634 return;
1635
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001636 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001637
Andre Guedes343f9352012-02-17 20:39:37 -03001638 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001639 goto unlock;
1640
1641 if (list_empty(&discov->resolve)) {
1642 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1643 goto unlock;
1644 }
1645
1646 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1647 if (e && hci_resolve_name(hdev, e) == 0) {
1648 e->name_state = NAME_PENDING;
1649 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1650 } else {
1651 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1652 }
1653
1654unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001655 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001656}
1657
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1659{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001660 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001661 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 int num_rsp = *((__u8 *) skb->data);
1663
1664 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1665
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001666 if (!num_rsp)
1667 return;
1668
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001670
Johan Hedberge17acd42011-03-30 23:57:16 +03001671 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg31754052012-01-04 13:39:52 +02001672 bool name_known;
1673
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 bacpy(&data.bdaddr, &info->bdaddr);
1675 data.pscan_rep_mode = info->pscan_rep_mode;
1676 data.pscan_period_mode = info->pscan_period_mode;
1677 data.pscan_mode = info->pscan_mode;
1678 memcpy(data.dev_class, info->dev_class, 3);
1679 data.clock_offset = info->clock_offset;
1680 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001681 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001682
1683 name_known = hci_inquiry_cache_update(hdev, &data, false);
Johan Hedberg48264f02011-11-09 13:58:58 +02001684 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Andre Guedes7d262f82012-01-10 18:20:49 -03001685 info->dev_class, 0, !name_known,
1686 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001688
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 hci_dev_unlock(hdev);
1690}
1691
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001692static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001694 struct hci_ev_conn_complete *ev = (void *) skb->data;
1695 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001697 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001698
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001700
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001701 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001702 if (!conn) {
1703 if (ev->link_type != SCO_LINK)
1704 goto unlock;
1705
1706 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1707 if (!conn)
1708 goto unlock;
1709
1710 conn->type = SCO_LINK;
1711 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001712
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001713 if (!ev->status) {
1714 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001715
1716 if (conn->type == ACL_LINK) {
1717 conn->state = BT_CONFIG;
1718 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001719 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001720 } else
1721 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001722
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001723 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001724 hci_conn_add_sysfs(conn);
1725
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001726 if (test_bit(HCI_AUTH, &hdev->flags))
1727 conn->link_mode |= HCI_LM_AUTH;
1728
1729 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1730 conn->link_mode |= HCI_LM_ENCRYPT;
1731
1732 /* Get remote features */
1733 if (conn->type == ACL_LINK) {
1734 struct hci_cp_read_remote_features cp;
1735 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001736 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1737 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001738 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001739
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001740 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001741 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001742 struct hci_cp_change_conn_ptype cp;
1743 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001744 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1745 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1746 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001747 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001748 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001749 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001750 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001751 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001752 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001753 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001754
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001755 if (conn->type == ACL_LINK)
1756 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001757
Marcel Holtmann769be972008-07-14 20:13:49 +02001758 if (ev->status) {
1759 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001760 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001761 } else if (ev->link_type != ACL_LINK)
1762 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001763
1764unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001766
1767 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768}
1769
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1771{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001772 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 int mask = hdev->link_mode;
1774
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001775 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1776 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777
1778 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1779
Szymon Janc138d22e2011-02-17 16:44:23 +01001780 if ((mask & HCI_LM_ACCEPT) &&
1781 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001783 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785
1786 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001787
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001788 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1789 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001790 memcpy(ie->data.dev_class, ev->dev_class, 3);
1791
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1793 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001794 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1795 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001796 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 hci_dev_unlock(hdev);
1798 return;
1799 }
1800 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001801
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 memcpy(conn->dev_class, ev->dev_class, 3);
1803 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001804
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 hci_dev_unlock(hdev);
1806
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001807 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1808 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001810 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001812 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1813 cp.role = 0x00; /* Become master */
1814 else
1815 cp.role = 0x01; /* Remain slave */
1816
1817 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1818 sizeof(cp), &cp);
1819 } else {
1820 struct hci_cp_accept_sync_conn_req cp;
1821
1822 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001823 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001824
1825 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1826 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1827 cp.max_latency = cpu_to_le16(0xffff);
1828 cp.content_format = cpu_to_le16(hdev->voice_setting);
1829 cp.retrans_effort = 0xff;
1830
1831 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1832 sizeof(cp), &cp);
1833 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 } else {
1835 /* Connection rejected */
1836 struct hci_cp_reject_conn_req cp;
1837
1838 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001839 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001840 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 }
1842}
1843
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1845{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001846 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001847 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848
1849 BT_DBG("%s status %d", hdev->name, ev->status);
1850
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 hci_dev_lock(hdev);
1852
Marcel Holtmann04837f62006-07-03 10:02:33 +02001853 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001854 if (!conn)
1855 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001856
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001857 if (ev->status == 0)
1858 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859
Johan Hedbergb644ba32012-01-17 21:48:47 +02001860 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1861 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001862 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001863 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1864 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001865 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001866 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001867 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001868 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001869
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001870 if (ev->status == 0) {
1871 hci_proto_disconn_cfm(conn, ev->reason);
1872 hci_conn_del(conn);
1873 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001874
1875unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876 hci_dev_unlock(hdev);
1877}
1878
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001879static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1880{
1881 struct hci_ev_auth_complete *ev = (void *) skb->data;
1882 struct hci_conn *conn;
1883
1884 BT_DBG("%s status %d", hdev->name, ev->status);
1885
1886 hci_dev_lock(hdev);
1887
1888 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001889 if (!conn)
1890 goto unlock;
1891
1892 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001893 if (!hci_conn_ssp_enabled(conn) &&
1894 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001895 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001896 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001897 conn->link_mode |= HCI_LM_AUTH;
1898 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001899 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001900 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001901 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
1902 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001903 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001904
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001905 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1906 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001907
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001908 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001909 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001910 struct hci_cp_set_conn_encrypt cp;
1911 cp.handle = ev->handle;
1912 cp.encrypt = 0x01;
1913 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1914 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001915 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001916 conn->state = BT_CONNECTED;
1917 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001918 hci_conn_put(conn);
1919 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001920 } else {
1921 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001922
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001923 hci_conn_hold(conn);
1924 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1925 hci_conn_put(conn);
1926 }
1927
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001928 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001929 if (!ev->status) {
1930 struct hci_cp_set_conn_encrypt cp;
1931 cp.handle = ev->handle;
1932 cp.encrypt = 0x01;
1933 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1934 &cp);
1935 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001936 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001937 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001938 }
1939 }
1940
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001941unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001942 hci_dev_unlock(hdev);
1943}
1944
1945static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1946{
Johan Hedberg127178d2010-11-18 22:22:29 +02001947 struct hci_ev_remote_name *ev = (void *) skb->data;
1948 struct hci_conn *conn;
1949
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001950 BT_DBG("%s", hdev->name);
1951
1952 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001953
1954 hci_dev_lock(hdev);
1955
1956 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001957
1958 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1959 goto check_auth;
1960
1961 if (ev->status == 0)
1962 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1963 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1964 else
1965 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1966
1967check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001968 if (!conn)
1969 goto unlock;
1970
1971 if (!hci_outgoing_auth_needed(hdev, conn))
1972 goto unlock;
1973
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001974 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001975 struct hci_cp_auth_requested cp;
1976 cp.handle = __cpu_to_le16(conn->handle);
1977 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1978 }
1979
Johan Hedberg79c6c702011-04-28 11:28:55 -07001980unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001981 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001982}
1983
1984static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1985{
1986 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1987 struct hci_conn *conn;
1988
1989 BT_DBG("%s status %d", hdev->name, ev->status);
1990
1991 hci_dev_lock(hdev);
1992
1993 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1994 if (conn) {
1995 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001996 if (ev->encrypt) {
1997 /* Encryption implies authentication */
1998 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001999 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002000 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002001 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002002 conn->link_mode &= ~HCI_LM_ENCRYPT;
2003 }
2004
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002005 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002006
Marcel Holtmannf8558552008-07-14 20:13:49 +02002007 if (conn->state == BT_CONFIG) {
2008 if (!ev->status)
2009 conn->state = BT_CONNECTED;
2010
2011 hci_proto_connect_cfm(conn, ev->status);
2012 hci_conn_put(conn);
2013 } else
2014 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002015 }
2016
2017 hci_dev_unlock(hdev);
2018}
2019
2020static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2021{
2022 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2023 struct hci_conn *conn;
2024
2025 BT_DBG("%s status %d", hdev->name, ev->status);
2026
2027 hci_dev_lock(hdev);
2028
2029 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2030 if (conn) {
2031 if (!ev->status)
2032 conn->link_mode |= HCI_LM_SECURE;
2033
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002034 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002035
2036 hci_key_change_cfm(conn, ev->status);
2037 }
2038
2039 hci_dev_unlock(hdev);
2040}
2041
2042static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2043{
2044 struct hci_ev_remote_features *ev = (void *) skb->data;
2045 struct hci_conn *conn;
2046
2047 BT_DBG("%s status %d", hdev->name, ev->status);
2048
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002049 hci_dev_lock(hdev);
2050
2051 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002052 if (!conn)
2053 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002054
Johan Hedbergccd556f2010-11-10 17:11:51 +02002055 if (!ev->status)
2056 memcpy(conn->features, ev->features, 8);
2057
2058 if (conn->state != BT_CONFIG)
2059 goto unlock;
2060
2061 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2062 struct hci_cp_read_remote_ext_features cp;
2063 cp.handle = ev->handle;
2064 cp.page = 0x01;
2065 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002066 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002067 goto unlock;
2068 }
2069
Johan Hedberg127178d2010-11-18 22:22:29 +02002070 if (!ev->status) {
2071 struct hci_cp_remote_name_req cp;
2072 memset(&cp, 0, sizeof(cp));
2073 bacpy(&cp.bdaddr, &conn->dst);
2074 cp.pscan_rep_mode = 0x02;
2075 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002076 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2077 mgmt_device_connected(hdev, &conn->dst, conn->type,
2078 conn->dst_type, NULL, 0,
2079 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002080
Johan Hedberg127178d2010-11-18 22:22:29 +02002081 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002082 conn->state = BT_CONNECTED;
2083 hci_proto_connect_cfm(conn, ev->status);
2084 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002085 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002086
Johan Hedbergccd556f2010-11-10 17:11:51 +02002087unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002088 hci_dev_unlock(hdev);
2089}
2090
2091static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2092{
2093 BT_DBG("%s", hdev->name);
2094}
2095
2096static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2097{
2098 BT_DBG("%s", hdev->name);
2099}
2100
2101static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2102{
2103 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2104 __u16 opcode;
2105
2106 skb_pull(skb, sizeof(*ev));
2107
2108 opcode = __le16_to_cpu(ev->opcode);
2109
2110 switch (opcode) {
2111 case HCI_OP_INQUIRY_CANCEL:
2112 hci_cc_inquiry_cancel(hdev, skb);
2113 break;
2114
2115 case HCI_OP_EXIT_PERIODIC_INQ:
2116 hci_cc_exit_periodic_inq(hdev, skb);
2117 break;
2118
2119 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2120 hci_cc_remote_name_req_cancel(hdev, skb);
2121 break;
2122
2123 case HCI_OP_ROLE_DISCOVERY:
2124 hci_cc_role_discovery(hdev, skb);
2125 break;
2126
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002127 case HCI_OP_READ_LINK_POLICY:
2128 hci_cc_read_link_policy(hdev, skb);
2129 break;
2130
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002131 case HCI_OP_WRITE_LINK_POLICY:
2132 hci_cc_write_link_policy(hdev, skb);
2133 break;
2134
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002135 case HCI_OP_READ_DEF_LINK_POLICY:
2136 hci_cc_read_def_link_policy(hdev, skb);
2137 break;
2138
2139 case HCI_OP_WRITE_DEF_LINK_POLICY:
2140 hci_cc_write_def_link_policy(hdev, skb);
2141 break;
2142
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002143 case HCI_OP_RESET:
2144 hci_cc_reset(hdev, skb);
2145 break;
2146
2147 case HCI_OP_WRITE_LOCAL_NAME:
2148 hci_cc_write_local_name(hdev, skb);
2149 break;
2150
2151 case HCI_OP_READ_LOCAL_NAME:
2152 hci_cc_read_local_name(hdev, skb);
2153 break;
2154
2155 case HCI_OP_WRITE_AUTH_ENABLE:
2156 hci_cc_write_auth_enable(hdev, skb);
2157 break;
2158
2159 case HCI_OP_WRITE_ENCRYPT_MODE:
2160 hci_cc_write_encrypt_mode(hdev, skb);
2161 break;
2162
2163 case HCI_OP_WRITE_SCAN_ENABLE:
2164 hci_cc_write_scan_enable(hdev, skb);
2165 break;
2166
2167 case HCI_OP_READ_CLASS_OF_DEV:
2168 hci_cc_read_class_of_dev(hdev, skb);
2169 break;
2170
2171 case HCI_OP_WRITE_CLASS_OF_DEV:
2172 hci_cc_write_class_of_dev(hdev, skb);
2173 break;
2174
2175 case HCI_OP_READ_VOICE_SETTING:
2176 hci_cc_read_voice_setting(hdev, skb);
2177 break;
2178
2179 case HCI_OP_WRITE_VOICE_SETTING:
2180 hci_cc_write_voice_setting(hdev, skb);
2181 break;
2182
2183 case HCI_OP_HOST_BUFFER_SIZE:
2184 hci_cc_host_buffer_size(hdev, skb);
2185 break;
2186
Marcel Holtmann333140b2008-07-14 20:13:48 +02002187 case HCI_OP_WRITE_SSP_MODE:
2188 hci_cc_write_ssp_mode(hdev, skb);
2189 break;
2190
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002191 case HCI_OP_READ_LOCAL_VERSION:
2192 hci_cc_read_local_version(hdev, skb);
2193 break;
2194
2195 case HCI_OP_READ_LOCAL_COMMANDS:
2196 hci_cc_read_local_commands(hdev, skb);
2197 break;
2198
2199 case HCI_OP_READ_LOCAL_FEATURES:
2200 hci_cc_read_local_features(hdev, skb);
2201 break;
2202
Andre Guedes971e3a42011-06-30 19:20:52 -03002203 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2204 hci_cc_read_local_ext_features(hdev, skb);
2205 break;
2206
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002207 case HCI_OP_READ_BUFFER_SIZE:
2208 hci_cc_read_buffer_size(hdev, skb);
2209 break;
2210
2211 case HCI_OP_READ_BD_ADDR:
2212 hci_cc_read_bd_addr(hdev, skb);
2213 break;
2214
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002215 case HCI_OP_READ_DATA_BLOCK_SIZE:
2216 hci_cc_read_data_block_size(hdev, skb);
2217 break;
2218
Johan Hedberg23bb5762010-12-21 23:01:27 +02002219 case HCI_OP_WRITE_CA_TIMEOUT:
2220 hci_cc_write_ca_timeout(hdev, skb);
2221 break;
2222
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002223 case HCI_OP_READ_FLOW_CONTROL_MODE:
2224 hci_cc_read_flow_control_mode(hdev, skb);
2225 break;
2226
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002227 case HCI_OP_READ_LOCAL_AMP_INFO:
2228 hci_cc_read_local_amp_info(hdev, skb);
2229 break;
2230
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002231 case HCI_OP_DELETE_STORED_LINK_KEY:
2232 hci_cc_delete_stored_link_key(hdev, skb);
2233 break;
2234
Johan Hedbergd5859e22011-01-25 01:19:58 +02002235 case HCI_OP_SET_EVENT_MASK:
2236 hci_cc_set_event_mask(hdev, skb);
2237 break;
2238
2239 case HCI_OP_WRITE_INQUIRY_MODE:
2240 hci_cc_write_inquiry_mode(hdev, skb);
2241 break;
2242
2243 case HCI_OP_READ_INQ_RSP_TX_POWER:
2244 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2245 break;
2246
2247 case HCI_OP_SET_EVENT_FLT:
2248 hci_cc_set_event_flt(hdev, skb);
2249 break;
2250
Johan Hedberg980e1a52011-01-22 06:10:07 +02002251 case HCI_OP_PIN_CODE_REPLY:
2252 hci_cc_pin_code_reply(hdev, skb);
2253 break;
2254
2255 case HCI_OP_PIN_CODE_NEG_REPLY:
2256 hci_cc_pin_code_neg_reply(hdev, skb);
2257 break;
2258
Szymon Jancc35938b2011-03-22 13:12:21 +01002259 case HCI_OP_READ_LOCAL_OOB_DATA:
2260 hci_cc_read_local_oob_data_reply(hdev, skb);
2261 break;
2262
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002263 case HCI_OP_LE_READ_BUFFER_SIZE:
2264 hci_cc_le_read_buffer_size(hdev, skb);
2265 break;
2266
Johan Hedberga5c29682011-02-19 12:05:57 -03002267 case HCI_OP_USER_CONFIRM_REPLY:
2268 hci_cc_user_confirm_reply(hdev, skb);
2269 break;
2270
2271 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2272 hci_cc_user_confirm_neg_reply(hdev, skb);
2273 break;
2274
Brian Gix1143d452011-11-23 08:28:34 -08002275 case HCI_OP_USER_PASSKEY_REPLY:
2276 hci_cc_user_passkey_reply(hdev, skb);
2277 break;
2278
2279 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2280 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002281
2282 case HCI_OP_LE_SET_SCAN_PARAM:
2283 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002284 break;
2285
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002286 case HCI_OP_LE_SET_SCAN_ENABLE:
2287 hci_cc_le_set_scan_enable(hdev, skb);
2288 break;
2289
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002290 case HCI_OP_LE_LTK_REPLY:
2291 hci_cc_le_ltk_reply(hdev, skb);
2292 break;
2293
2294 case HCI_OP_LE_LTK_NEG_REPLY:
2295 hci_cc_le_ltk_neg_reply(hdev, skb);
2296 break;
2297
Andre Guedesf9b49302011-06-30 19:20:53 -03002298 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2299 hci_cc_write_le_host_supported(hdev, skb);
2300 break;
2301
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002302 default:
2303 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2304 break;
2305 }
2306
Ville Tervo6bd32322011-02-16 16:32:41 +02002307 if (ev->opcode != HCI_OP_NOP)
2308 del_timer(&hdev->cmd_timer);
2309
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002310 if (ev->ncmd) {
2311 atomic_set(&hdev->cmd_cnt, 1);
2312 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002313 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002314 }
2315}
2316
2317static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2318{
2319 struct hci_ev_cmd_status *ev = (void *) skb->data;
2320 __u16 opcode;
2321
2322 skb_pull(skb, sizeof(*ev));
2323
2324 opcode = __le16_to_cpu(ev->opcode);
2325
2326 switch (opcode) {
2327 case HCI_OP_INQUIRY:
2328 hci_cs_inquiry(hdev, ev->status);
2329 break;
2330
2331 case HCI_OP_CREATE_CONN:
2332 hci_cs_create_conn(hdev, ev->status);
2333 break;
2334
2335 case HCI_OP_ADD_SCO:
2336 hci_cs_add_sco(hdev, ev->status);
2337 break;
2338
Marcel Holtmannf8558552008-07-14 20:13:49 +02002339 case HCI_OP_AUTH_REQUESTED:
2340 hci_cs_auth_requested(hdev, ev->status);
2341 break;
2342
2343 case HCI_OP_SET_CONN_ENCRYPT:
2344 hci_cs_set_conn_encrypt(hdev, ev->status);
2345 break;
2346
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002347 case HCI_OP_REMOTE_NAME_REQ:
2348 hci_cs_remote_name_req(hdev, ev->status);
2349 break;
2350
Marcel Holtmann769be972008-07-14 20:13:49 +02002351 case HCI_OP_READ_REMOTE_FEATURES:
2352 hci_cs_read_remote_features(hdev, ev->status);
2353 break;
2354
2355 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2356 hci_cs_read_remote_ext_features(hdev, ev->status);
2357 break;
2358
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002359 case HCI_OP_SETUP_SYNC_CONN:
2360 hci_cs_setup_sync_conn(hdev, ev->status);
2361 break;
2362
2363 case HCI_OP_SNIFF_MODE:
2364 hci_cs_sniff_mode(hdev, ev->status);
2365 break;
2366
2367 case HCI_OP_EXIT_SNIFF_MODE:
2368 hci_cs_exit_sniff_mode(hdev, ev->status);
2369 break;
2370
Johan Hedberg8962ee72011-01-20 12:40:27 +02002371 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002372 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002373 break;
2374
Ville Tervofcd89c02011-02-10 22:38:47 -03002375 case HCI_OP_LE_CREATE_CONN:
2376 hci_cs_le_create_conn(hdev, ev->status);
2377 break;
2378
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002379 case HCI_OP_LE_START_ENC:
2380 hci_cs_le_start_enc(hdev, ev->status);
2381 break;
2382
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002383 default:
2384 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2385 break;
2386 }
2387
Ville Tervo6bd32322011-02-16 16:32:41 +02002388 if (ev->opcode != HCI_OP_NOP)
2389 del_timer(&hdev->cmd_timer);
2390
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002391 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002392 atomic_set(&hdev->cmd_cnt, 1);
2393 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002394 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002395 }
2396}
2397
2398static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2399{
2400 struct hci_ev_role_change *ev = (void *) skb->data;
2401 struct hci_conn *conn;
2402
2403 BT_DBG("%s status %d", hdev->name, ev->status);
2404
2405 hci_dev_lock(hdev);
2406
2407 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2408 if (conn) {
2409 if (!ev->status) {
2410 if (ev->role)
2411 conn->link_mode &= ~HCI_LM_MASTER;
2412 else
2413 conn->link_mode |= HCI_LM_MASTER;
2414 }
2415
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002416 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002417
2418 hci_role_switch_cfm(conn, ev->status, ev->role);
2419 }
2420
2421 hci_dev_unlock(hdev);
2422}
2423
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2425{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002426 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427 int i;
2428
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002429 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2430 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2431 return;
2432 }
2433
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002434 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2435 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002436 BT_DBG("%s bad parameters", hdev->name);
2437 return;
2438 }
2439
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002440 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2441
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002442 for (i = 0; i < ev->num_hndl; i++) {
2443 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002444 struct hci_conn *conn;
2445 __u16 handle, count;
2446
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002447 handle = __le16_to_cpu(info->handle);
2448 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449
2450 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002451 if (!conn)
2452 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002453
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002454 conn->sent -= count;
2455
2456 switch (conn->type) {
2457 case ACL_LINK:
2458 hdev->acl_cnt += count;
2459 if (hdev->acl_cnt > hdev->acl_pkts)
2460 hdev->acl_cnt = hdev->acl_pkts;
2461 break;
2462
2463 case LE_LINK:
2464 if (hdev->le_pkts) {
2465 hdev->le_cnt += count;
2466 if (hdev->le_cnt > hdev->le_pkts)
2467 hdev->le_cnt = hdev->le_pkts;
2468 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002469 hdev->acl_cnt += count;
2470 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002471 hdev->acl_cnt = hdev->acl_pkts;
2472 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002473 break;
2474
2475 case SCO_LINK:
2476 hdev->sco_cnt += count;
2477 if (hdev->sco_cnt > hdev->sco_pkts)
2478 hdev->sco_cnt = hdev->sco_pkts;
2479 break;
2480
2481 default:
2482 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2483 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002484 }
2485 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002486
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002487 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002488}
2489
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002490static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2491 struct sk_buff *skb)
2492{
2493 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2494 int i;
2495
2496 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2497 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2498 return;
2499 }
2500
2501 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2502 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2503 BT_DBG("%s bad parameters", hdev->name);
2504 return;
2505 }
2506
2507 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2508 ev->num_hndl);
2509
2510 for (i = 0; i < ev->num_hndl; i++) {
2511 struct hci_comp_blocks_info *info = &ev->handles[i];
2512 struct hci_conn *conn;
2513 __u16 handle, block_count;
2514
2515 handle = __le16_to_cpu(info->handle);
2516 block_count = __le16_to_cpu(info->blocks);
2517
2518 conn = hci_conn_hash_lookup_handle(hdev, handle);
2519 if (!conn)
2520 continue;
2521
2522 conn->sent -= block_count;
2523
2524 switch (conn->type) {
2525 case ACL_LINK:
2526 hdev->block_cnt += block_count;
2527 if (hdev->block_cnt > hdev->num_blocks)
2528 hdev->block_cnt = hdev->num_blocks;
2529 break;
2530
2531 default:
2532 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2533 break;
2534 }
2535 }
2536
2537 queue_work(hdev->workqueue, &hdev->tx_work);
2538}
2539
Marcel Holtmann04837f62006-07-03 10:02:33 +02002540static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002542 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002543 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544
2545 BT_DBG("%s status %d", hdev->name, ev->status);
2546
2547 hci_dev_lock(hdev);
2548
Marcel Holtmann04837f62006-07-03 10:02:33 +02002549 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2550 if (conn) {
2551 conn->mode = ev->mode;
2552 conn->interval = __le16_to_cpu(ev->interval);
2553
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002554 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002555 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002556 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002557 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002558 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002559 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002560
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002561 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002562 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002563 }
2564
2565 hci_dev_unlock(hdev);
2566}
2567
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2569{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002570 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2571 struct hci_conn *conn;
2572
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002573 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002574
2575 hci_dev_lock(hdev);
2576
2577 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002578 if (!conn)
2579 goto unlock;
2580
2581 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002582 hci_conn_hold(conn);
2583 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2584 hci_conn_put(conn);
2585 }
2586
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002587 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002588 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2589 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002590 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002591 u8 secure;
2592
2593 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2594 secure = 1;
2595 else
2596 secure = 0;
2597
Johan Hedberg744cf192011-11-08 20:40:14 +02002598 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002599 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002600
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002601unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002602 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002603}
2604
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2606{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002607 struct hci_ev_link_key_req *ev = (void *) skb->data;
2608 struct hci_cp_link_key_reply cp;
2609 struct hci_conn *conn;
2610 struct link_key *key;
2611
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002612 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002613
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002614 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002615 return;
2616
2617 hci_dev_lock(hdev);
2618
2619 key = hci_find_link_key(hdev, &ev->bdaddr);
2620 if (!key) {
2621 BT_DBG("%s link key not found for %s", hdev->name,
2622 batostr(&ev->bdaddr));
2623 goto not_found;
2624 }
2625
2626 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2627 batostr(&ev->bdaddr));
2628
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002629 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002630 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002631 BT_DBG("%s ignoring debug key", hdev->name);
2632 goto not_found;
2633 }
2634
2635 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002636 if (conn) {
2637 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2638 conn->auth_type != 0xff &&
2639 (conn->auth_type & 0x01)) {
2640 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2641 goto not_found;
2642 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002643
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002644 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2645 conn->pending_sec_level == BT_SECURITY_HIGH) {
2646 BT_DBG("%s ignoring key unauthenticated for high \
2647 security", hdev->name);
2648 goto not_found;
2649 }
2650
2651 conn->key_type = key->type;
2652 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002653 }
2654
2655 bacpy(&cp.bdaddr, &ev->bdaddr);
2656 memcpy(cp.link_key, key->val, 16);
2657
2658 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2659
2660 hci_dev_unlock(hdev);
2661
2662 return;
2663
2664not_found:
2665 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2666 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667}
2668
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2670{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002671 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2672 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002673 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002674
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002675 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002676
2677 hci_dev_lock(hdev);
2678
2679 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2680 if (conn) {
2681 hci_conn_hold(conn);
2682 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002683 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002684
2685 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2686 conn->key_type = ev->key_type;
2687
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002688 hci_conn_put(conn);
2689 }
2690
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002691 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002692 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002693 ev->key_type, pin_len);
2694
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002695 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696}
2697
Marcel Holtmann04837f62006-07-03 10:02:33 +02002698static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2699{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002700 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002701 struct hci_conn *conn;
2702
2703 BT_DBG("%s status %d", hdev->name, ev->status);
2704
2705 hci_dev_lock(hdev);
2706
2707 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708 if (conn && !ev->status) {
2709 struct inquiry_entry *ie;
2710
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002711 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2712 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002713 ie->data.clock_offset = ev->clock_offset;
2714 ie->timestamp = jiffies;
2715 }
2716 }
2717
2718 hci_dev_unlock(hdev);
2719}
2720
Marcel Holtmanna8746412008-07-14 20:13:46 +02002721static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2722{
2723 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2724 struct hci_conn *conn;
2725
2726 BT_DBG("%s status %d", hdev->name, ev->status);
2727
2728 hci_dev_lock(hdev);
2729
2730 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2731 if (conn && !ev->status)
2732 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2733
2734 hci_dev_unlock(hdev);
2735}
2736
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002737static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2738{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002739 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002740 struct inquiry_entry *ie;
2741
2742 BT_DBG("%s", hdev->name);
2743
2744 hci_dev_lock(hdev);
2745
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002746 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2747 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002748 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2749 ie->timestamp = jiffies;
2750 }
2751
2752 hci_dev_unlock(hdev);
2753}
2754
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002755static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2756{
2757 struct inquiry_data data;
2758 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg31754052012-01-04 13:39:52 +02002759 bool name_known;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002760
2761 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2762
2763 if (!num_rsp)
2764 return;
2765
2766 hci_dev_lock(hdev);
2767
2768 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002769 struct inquiry_info_with_rssi_and_pscan_mode *info;
2770 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002771
Johan Hedberge17acd42011-03-30 23:57:16 +03002772 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002773 bacpy(&data.bdaddr, &info->bdaddr);
2774 data.pscan_rep_mode = info->pscan_rep_mode;
2775 data.pscan_period_mode = info->pscan_period_mode;
2776 data.pscan_mode = info->pscan_mode;
2777 memcpy(data.dev_class, info->dev_class, 3);
2778 data.clock_offset = info->clock_offset;
2779 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002780 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002781
2782 name_known = hci_inquiry_cache_update(hdev, &data,
2783 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002784 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002785 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002786 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002787 }
2788 } else {
2789 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2790
Johan Hedberge17acd42011-03-30 23:57:16 +03002791 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002792 bacpy(&data.bdaddr, &info->bdaddr);
2793 data.pscan_rep_mode = info->pscan_rep_mode;
2794 data.pscan_period_mode = info->pscan_period_mode;
2795 data.pscan_mode = 0x00;
2796 memcpy(data.dev_class, info->dev_class, 3);
2797 data.clock_offset = info->clock_offset;
2798 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002799 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002800 name_known = hci_inquiry_cache_update(hdev, &data,
2801 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002802 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002803 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002804 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002805 }
2806 }
2807
2808 hci_dev_unlock(hdev);
2809}
2810
2811static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2812{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002813 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2814 struct hci_conn *conn;
2815
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002816 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002817
Marcel Holtmann41a96212008-07-14 20:13:48 +02002818 hci_dev_lock(hdev);
2819
2820 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002821 if (!conn)
2822 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002823
Johan Hedbergccd556f2010-11-10 17:11:51 +02002824 if (!ev->status && ev->page == 0x01) {
2825 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002826
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002827 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2828 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002829 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002830
Johan Hedberg58a681e2012-01-16 06:47:28 +02002831 if (ev->features[0] & 0x01)
2832 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002833 }
2834
Johan Hedbergccd556f2010-11-10 17:11:51 +02002835 if (conn->state != BT_CONFIG)
2836 goto unlock;
2837
Johan Hedberg127178d2010-11-18 22:22:29 +02002838 if (!ev->status) {
2839 struct hci_cp_remote_name_req cp;
2840 memset(&cp, 0, sizeof(cp));
2841 bacpy(&cp.bdaddr, &conn->dst);
2842 cp.pscan_rep_mode = 0x02;
2843 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002844 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2845 mgmt_device_connected(hdev, &conn->dst, conn->type,
2846 conn->dst_type, NULL, 0,
2847 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002848
Johan Hedberg127178d2010-11-18 22:22:29 +02002849 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002850 conn->state = BT_CONNECTED;
2851 hci_proto_connect_cfm(conn, ev->status);
2852 hci_conn_put(conn);
2853 }
2854
2855unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002856 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002857}
2858
2859static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2860{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002861 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2862 struct hci_conn *conn;
2863
2864 BT_DBG("%s status %d", hdev->name, ev->status);
2865
2866 hci_dev_lock(hdev);
2867
2868 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002869 if (!conn) {
2870 if (ev->link_type == ESCO_LINK)
2871 goto unlock;
2872
2873 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2874 if (!conn)
2875 goto unlock;
2876
2877 conn->type = SCO_LINK;
2878 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002879
Marcel Holtmann732547f2009-04-19 19:14:14 +02002880 switch (ev->status) {
2881 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002882 conn->handle = __le16_to_cpu(ev->handle);
2883 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002884
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002885 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002886 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002887 break;
2888
Stephen Coe705e5712010-02-16 11:29:44 -05002889 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002890 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002891 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002892 case 0x1f: /* Unspecified error */
2893 if (conn->out && conn->attempt < 2) {
2894 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2895 (hdev->esco_type & EDR_ESCO_MASK);
2896 hci_setup_sync(conn, conn->link->handle);
2897 goto unlock;
2898 }
2899 /* fall through */
2900
2901 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002902 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002903 break;
2904 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002905
2906 hci_proto_connect_cfm(conn, ev->status);
2907 if (ev->status)
2908 hci_conn_del(conn);
2909
2910unlock:
2911 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002912}
2913
2914static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2915{
2916 BT_DBG("%s", hdev->name);
2917}
2918
Marcel Holtmann04837f62006-07-03 10:02:33 +02002919static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2920{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002921 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002922
2923 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002924}
2925
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002926static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2927{
2928 struct inquiry_data data;
2929 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2930 int num_rsp = *((__u8 *) skb->data);
2931
2932 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2933
2934 if (!num_rsp)
2935 return;
2936
2937 hci_dev_lock(hdev);
2938
Johan Hedberge17acd42011-03-30 23:57:16 +03002939 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg561aafb2012-01-04 13:31:59 +02002940 bool name_known;
2941
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002942 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002943 data.pscan_rep_mode = info->pscan_rep_mode;
2944 data.pscan_period_mode = info->pscan_period_mode;
2945 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002946 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002947 data.clock_offset = info->clock_offset;
2948 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002949 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002950
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002951 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002952 name_known = eir_has_data_type(info->data,
2953 sizeof(info->data),
2954 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002955 else
2956 name_known = true;
2957
Johan Hedberg31754052012-01-04 13:39:52 +02002958 name_known = hci_inquiry_cache_update(hdev, &data, name_known);
Johan Hedberg48264f02011-11-09 13:58:58 +02002959 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002960 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002961 !name_known, info->data,
2962 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002963 }
2964
2965 hci_dev_unlock(hdev);
2966}
2967
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002968static inline u8 hci_get_auth_req(struct hci_conn *conn)
2969{
2970 /* If remote requests dedicated bonding follow that lead */
2971 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2972 /* If both remote and local IO capabilities allow MITM
2973 * protection then require it, otherwise don't */
2974 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2975 return 0x02;
2976 else
2977 return 0x03;
2978 }
2979
2980 /* If remote requests no-bonding follow that lead */
2981 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002982 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002983
2984 return conn->auth_type;
2985}
2986
Marcel Holtmann04936842008-07-14 20:13:48 +02002987static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2988{
2989 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2990 struct hci_conn *conn;
2991
2992 BT_DBG("%s", hdev->name);
2993
2994 hci_dev_lock(hdev);
2995
2996 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002997 if (!conn)
2998 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002999
Johan Hedberg03b555e2011-01-04 15:40:05 +02003000 hci_conn_hold(conn);
3001
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003002 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003003 goto unlock;
3004
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003005 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003006 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003007 struct hci_cp_io_capability_reply cp;
3008
3009 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303010 /* Change the IO capability from KeyboardDisplay
3011 * to DisplayYesNo as it is not supported by BT spec. */
3012 cp.capability = (conn->io_capability == 0x04) ?
3013 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003014 conn->auth_type = hci_get_auth_req(conn);
3015 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003016
Johan Hedberg58a681e2012-01-16 06:47:28 +02003017 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003018 hci_find_remote_oob_data(hdev, &conn->dst))
3019 cp.oob_data = 0x01;
3020 else
3021 cp.oob_data = 0x00;
3022
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003023 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3024 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003025 } else {
3026 struct hci_cp_io_capability_neg_reply cp;
3027
3028 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003029 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003030
3031 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3032 sizeof(cp), &cp);
3033 }
3034
3035unlock:
3036 hci_dev_unlock(hdev);
3037}
3038
3039static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3040{
3041 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3042 struct hci_conn *conn;
3043
3044 BT_DBG("%s", hdev->name);
3045
3046 hci_dev_lock(hdev);
3047
3048 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3049 if (!conn)
3050 goto unlock;
3051
Johan Hedberg03b555e2011-01-04 15:40:05 +02003052 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003053 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003054 if (ev->oob_data)
3055 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003056
3057unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003058 hci_dev_unlock(hdev);
3059}
3060
Johan Hedberga5c29682011-02-19 12:05:57 -03003061static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3062 struct sk_buff *skb)
3063{
3064 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003065 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003066 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003067
3068 BT_DBG("%s", hdev->name);
3069
3070 hci_dev_lock(hdev);
3071
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003072 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003073 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003074
Johan Hedberg7a828902011-04-28 11:28:53 -07003075 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3076 if (!conn)
3077 goto unlock;
3078
3079 loc_mitm = (conn->auth_type & 0x01);
3080 rem_mitm = (conn->remote_auth & 0x01);
3081
3082 /* If we require MITM but the remote device can't provide that
3083 * (it has NoInputNoOutput) then reject the confirmation
3084 * request. The only exception is when we're dedicated bonding
3085 * initiators (connect_cfm_cb set) since then we always have the MITM
3086 * bit set. */
3087 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3088 BT_DBG("Rejecting request: remote device can't provide MITM");
3089 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3090 sizeof(ev->bdaddr), &ev->bdaddr);
3091 goto unlock;
3092 }
3093
3094 /* If no side requires MITM protection; auto-accept */
3095 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3096 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003097
3098 /* If we're not the initiators request authorization to
3099 * proceed from user space (mgmt_user_confirm with
3100 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003101 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003102 BT_DBG("Confirming auto-accept as acceptor");
3103 confirm_hint = 1;
3104 goto confirm;
3105 }
3106
Johan Hedberg9f616562011-04-28 11:28:54 -07003107 BT_DBG("Auto-accept of user confirmation with %ums delay",
3108 hdev->auto_accept_delay);
3109
3110 if (hdev->auto_accept_delay > 0) {
3111 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3112 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3113 goto unlock;
3114 }
3115
Johan Hedberg7a828902011-04-28 11:28:53 -07003116 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3117 sizeof(ev->bdaddr), &ev->bdaddr);
3118 goto unlock;
3119 }
3120
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003121confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003122 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003123 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003124
3125unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003126 hci_dev_unlock(hdev);
3127}
3128
Brian Gix1143d452011-11-23 08:28:34 -08003129static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3130 struct sk_buff *skb)
3131{
3132 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3133
3134 BT_DBG("%s", hdev->name);
3135
3136 hci_dev_lock(hdev);
3137
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003138 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003139 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003140
3141 hci_dev_unlock(hdev);
3142}
3143
Marcel Holtmann04936842008-07-14 20:13:48 +02003144static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3145{
3146 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3147 struct hci_conn *conn;
3148
3149 BT_DBG("%s", hdev->name);
3150
3151 hci_dev_lock(hdev);
3152
3153 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003154 if (!conn)
3155 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003156
Johan Hedberg2a611692011-02-19 12:06:00 -03003157 /* To avoid duplicate auth_failed events to user space we check
3158 * the HCI_CONN_AUTH_PEND flag which will be set if we
3159 * initiated the authentication. A traditional auth_complete
3160 * event gets always produced as initiator and is also mapped to
3161 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003162 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003163 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3164 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003165
3166 hci_conn_put(conn);
3167
3168unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003169 hci_dev_unlock(hdev);
3170}
3171
Marcel Holtmann41a96212008-07-14 20:13:48 +02003172static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3173{
3174 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3175 struct inquiry_entry *ie;
3176
3177 BT_DBG("%s", hdev->name);
3178
3179 hci_dev_lock(hdev);
3180
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003181 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3182 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003183 ie->data.ssp_mode = (ev->features[0] & 0x01);
3184
3185 hci_dev_unlock(hdev);
3186}
3187
Szymon Janc2763eda2011-03-22 13:12:22 +01003188static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3189 struct sk_buff *skb)
3190{
3191 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3192 struct oob_data *data;
3193
3194 BT_DBG("%s", hdev->name);
3195
3196 hci_dev_lock(hdev);
3197
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003198 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003199 goto unlock;
3200
Szymon Janc2763eda2011-03-22 13:12:22 +01003201 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3202 if (data) {
3203 struct hci_cp_remote_oob_data_reply cp;
3204
3205 bacpy(&cp.bdaddr, &ev->bdaddr);
3206 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3207 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3208
3209 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3210 &cp);
3211 } else {
3212 struct hci_cp_remote_oob_data_neg_reply cp;
3213
3214 bacpy(&cp.bdaddr, &ev->bdaddr);
3215 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3216 &cp);
3217 }
3218
Szymon Jance1ba1f12011-04-06 13:01:59 +02003219unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003220 hci_dev_unlock(hdev);
3221}
3222
Ville Tervofcd89c02011-02-10 22:38:47 -03003223static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3224{
3225 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3226 struct hci_conn *conn;
3227
3228 BT_DBG("%s status %d", hdev->name, ev->status);
3229
3230 hci_dev_lock(hdev);
3231
3232 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003233 if (!conn) {
3234 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3235 if (!conn) {
3236 BT_ERR("No memory for new connection");
3237 hci_dev_unlock(hdev);
3238 return;
3239 }
Andre Guedes29b79882011-05-31 14:20:54 -03003240
3241 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003242 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003243
3244 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003245 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3246 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003247 hci_proto_connect_cfm(conn, ev->status);
3248 conn->state = BT_CLOSED;
3249 hci_conn_del(conn);
3250 goto unlock;
3251 }
3252
Johan Hedbergb644ba32012-01-17 21:48:47 +02003253 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3254 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3255 conn->dst_type, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003256
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003257 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003258 conn->handle = __le16_to_cpu(ev->handle);
3259 conn->state = BT_CONNECTED;
3260
3261 hci_conn_hold_device(conn);
3262 hci_conn_add_sysfs(conn);
3263
3264 hci_proto_connect_cfm(conn, ev->status);
3265
3266unlock:
3267 hci_dev_unlock(hdev);
3268}
3269
Andre Guedes9aa04c92011-05-26 16:23:51 -03003270static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3271 struct sk_buff *skb)
3272{
Andre Guedese95beb42011-09-26 20:48:35 -03003273 u8 num_reports = skb->data[0];
3274 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003275 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003276
3277 hci_dev_lock(hdev);
3278
Andre Guedese95beb42011-09-26 20:48:35 -03003279 while (num_reports--) {
3280 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003281
Andre Guedes9aa04c92011-05-26 16:23:51 -03003282 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003283
Andre Guedes3c9e9192012-01-10 18:20:50 -03003284 rssi = ev->data[ev->length];
3285 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3286 NULL, rssi, 0, ev->data, ev->length);
3287
Andre Guedese95beb42011-09-26 20:48:35 -03003288 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003289 }
3290
3291 hci_dev_unlock(hdev);
3292}
3293
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003294static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3295 struct sk_buff *skb)
3296{
3297 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3298 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003299 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003300 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003301 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003302
3303 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3304
3305 hci_dev_lock(hdev);
3306
3307 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003308 if (conn == NULL)
3309 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003310
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003311 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3312 if (ltk == NULL)
3313 goto not_found;
3314
3315 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003316 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003317
3318 if (ltk->authenticated)
3319 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003320
3321 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3322
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003323 if (ltk->type & HCI_SMP_STK) {
3324 list_del(&ltk->list);
3325 kfree(ltk);
3326 }
3327
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003328 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003329
3330 return;
3331
3332not_found:
3333 neg.handle = ev->handle;
3334 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3335 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003336}
3337
Ville Tervofcd89c02011-02-10 22:38:47 -03003338static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3339{
3340 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3341
3342 skb_pull(skb, sizeof(*le_ev));
3343
3344 switch (le_ev->subevent) {
3345 case HCI_EV_LE_CONN_COMPLETE:
3346 hci_le_conn_complete_evt(hdev, skb);
3347 break;
3348
Andre Guedes9aa04c92011-05-26 16:23:51 -03003349 case HCI_EV_LE_ADVERTISING_REPORT:
3350 hci_le_adv_report_evt(hdev, skb);
3351 break;
3352
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003353 case HCI_EV_LE_LTK_REQ:
3354 hci_le_ltk_request_evt(hdev, skb);
3355 break;
3356
Ville Tervofcd89c02011-02-10 22:38:47 -03003357 default:
3358 break;
3359 }
3360}
3361
Linus Torvalds1da177e2005-04-16 15:20:36 -07003362void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3363{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003364 struct hci_event_hdr *hdr = (void *) skb->data;
3365 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003366
3367 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3368
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003369 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003370 case HCI_EV_INQUIRY_COMPLETE:
3371 hci_inquiry_complete_evt(hdev, skb);
3372 break;
3373
3374 case HCI_EV_INQUIRY_RESULT:
3375 hci_inquiry_result_evt(hdev, skb);
3376 break;
3377
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003378 case HCI_EV_CONN_COMPLETE:
3379 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003380 break;
3381
Linus Torvalds1da177e2005-04-16 15:20:36 -07003382 case HCI_EV_CONN_REQUEST:
3383 hci_conn_request_evt(hdev, skb);
3384 break;
3385
Linus Torvalds1da177e2005-04-16 15:20:36 -07003386 case HCI_EV_DISCONN_COMPLETE:
3387 hci_disconn_complete_evt(hdev, skb);
3388 break;
3389
Linus Torvalds1da177e2005-04-16 15:20:36 -07003390 case HCI_EV_AUTH_COMPLETE:
3391 hci_auth_complete_evt(hdev, skb);
3392 break;
3393
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003394 case HCI_EV_REMOTE_NAME:
3395 hci_remote_name_evt(hdev, skb);
3396 break;
3397
Linus Torvalds1da177e2005-04-16 15:20:36 -07003398 case HCI_EV_ENCRYPT_CHANGE:
3399 hci_encrypt_change_evt(hdev, skb);
3400 break;
3401
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003402 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3403 hci_change_link_key_complete_evt(hdev, skb);
3404 break;
3405
3406 case HCI_EV_REMOTE_FEATURES:
3407 hci_remote_features_evt(hdev, skb);
3408 break;
3409
3410 case HCI_EV_REMOTE_VERSION:
3411 hci_remote_version_evt(hdev, skb);
3412 break;
3413
3414 case HCI_EV_QOS_SETUP_COMPLETE:
3415 hci_qos_setup_complete_evt(hdev, skb);
3416 break;
3417
3418 case HCI_EV_CMD_COMPLETE:
3419 hci_cmd_complete_evt(hdev, skb);
3420 break;
3421
3422 case HCI_EV_CMD_STATUS:
3423 hci_cmd_status_evt(hdev, skb);
3424 break;
3425
3426 case HCI_EV_ROLE_CHANGE:
3427 hci_role_change_evt(hdev, skb);
3428 break;
3429
3430 case HCI_EV_NUM_COMP_PKTS:
3431 hci_num_comp_pkts_evt(hdev, skb);
3432 break;
3433
3434 case HCI_EV_MODE_CHANGE:
3435 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003436 break;
3437
3438 case HCI_EV_PIN_CODE_REQ:
3439 hci_pin_code_request_evt(hdev, skb);
3440 break;
3441
3442 case HCI_EV_LINK_KEY_REQ:
3443 hci_link_key_request_evt(hdev, skb);
3444 break;
3445
3446 case HCI_EV_LINK_KEY_NOTIFY:
3447 hci_link_key_notify_evt(hdev, skb);
3448 break;
3449
3450 case HCI_EV_CLOCK_OFFSET:
3451 hci_clock_offset_evt(hdev, skb);
3452 break;
3453
Marcel Holtmanna8746412008-07-14 20:13:46 +02003454 case HCI_EV_PKT_TYPE_CHANGE:
3455 hci_pkt_type_change_evt(hdev, skb);
3456 break;
3457
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003458 case HCI_EV_PSCAN_REP_MODE:
3459 hci_pscan_rep_mode_evt(hdev, skb);
3460 break;
3461
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003462 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3463 hci_inquiry_result_with_rssi_evt(hdev, skb);
3464 break;
3465
3466 case HCI_EV_REMOTE_EXT_FEATURES:
3467 hci_remote_ext_features_evt(hdev, skb);
3468 break;
3469
3470 case HCI_EV_SYNC_CONN_COMPLETE:
3471 hci_sync_conn_complete_evt(hdev, skb);
3472 break;
3473
3474 case HCI_EV_SYNC_CONN_CHANGED:
3475 hci_sync_conn_changed_evt(hdev, skb);
3476 break;
3477
Marcel Holtmann04837f62006-07-03 10:02:33 +02003478 case HCI_EV_SNIFF_SUBRATE:
3479 hci_sniff_subrate_evt(hdev, skb);
3480 break;
3481
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003482 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3483 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003484 break;
3485
Marcel Holtmann04936842008-07-14 20:13:48 +02003486 case HCI_EV_IO_CAPA_REQUEST:
3487 hci_io_capa_request_evt(hdev, skb);
3488 break;
3489
Johan Hedberg03b555e2011-01-04 15:40:05 +02003490 case HCI_EV_IO_CAPA_REPLY:
3491 hci_io_capa_reply_evt(hdev, skb);
3492 break;
3493
Johan Hedberga5c29682011-02-19 12:05:57 -03003494 case HCI_EV_USER_CONFIRM_REQUEST:
3495 hci_user_confirm_request_evt(hdev, skb);
3496 break;
3497
Brian Gix1143d452011-11-23 08:28:34 -08003498 case HCI_EV_USER_PASSKEY_REQUEST:
3499 hci_user_passkey_request_evt(hdev, skb);
3500 break;
3501
Marcel Holtmann04936842008-07-14 20:13:48 +02003502 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3503 hci_simple_pair_complete_evt(hdev, skb);
3504 break;
3505
Marcel Holtmann41a96212008-07-14 20:13:48 +02003506 case HCI_EV_REMOTE_HOST_FEATURES:
3507 hci_remote_host_features_evt(hdev, skb);
3508 break;
3509
Ville Tervofcd89c02011-02-10 22:38:47 -03003510 case HCI_EV_LE_META:
3511 hci_le_meta_evt(hdev, skb);
3512 break;
3513
Szymon Janc2763eda2011-03-22 13:12:22 +01003514 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3515 hci_remote_oob_data_request_evt(hdev, skb);
3516 break;
3517
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003518 case HCI_EV_NUM_COMP_BLOCKS:
3519 hci_num_comp_blocks_evt(hdev, skb);
3520 break;
3521
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003522 default:
3523 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003524 break;
3525 }
3526
3527 kfree_skb(skb);
3528 hdev->stat.evt_rx++;
3529}