blob: 498b71a0579acddb6523aa0b2a1623595b3397e1 [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
Johan Hedberg06199cf2012-02-22 16:37:11 +0200542 if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
Andre Guedese6100a22011-06-30 19:20:54 -0300543 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 Hedberg54d04db2012-02-22 15:47:48 +0200560 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
561 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
562 u8 mode = 0x01;
563 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
564 sizeof(mode), &mode);
565 } else {
566 struct hci_cp_write_eir cp;
567
568 memset(hdev->eir, 0, sizeof(hdev->eir));
569 memset(&cp, 0, sizeof(cp));
570
571 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
572 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200573 }
574
575 if (hdev->features[3] & LMP_RSSI_INQ)
576 hci_setup_inquiry_mode(hdev);
577
578 if (hdev->features[7] & LMP_INQ_TX_PWR)
579 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300580
581 if (hdev->features[7] & LMP_EXTFEATURES) {
582 struct hci_cp_read_local_ext_features cp;
583
584 cp.page = 0x01;
585 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
586 sizeof(cp), &cp);
587 }
Andre Guedese6100a22011-06-30 19:20:54 -0300588
Johan Hedberg47990ea2012-02-22 11:58:37 +0200589 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
590 u8 enable = 1;
591 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE,
592 sizeof(enable), &enable);
593 }
594
Andre Guedese6100a22011-06-30 19:20:54 -0300595 if (hdev->features[4] & LMP_LE)
596 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200597}
598
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200599static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
600{
601 struct hci_rp_read_local_version *rp = (void *) skb->data;
602
603 BT_DBG("%s status 0x%x", hdev->name, rp->status);
604
605 if (rp->status)
606 return;
607
608 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200609 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200610 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200611 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200612 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200613
614 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
615 hdev->manufacturer,
616 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200617
618 if (test_bit(HCI_INIT, &hdev->flags))
619 hci_setup(hdev);
620}
621
622static void hci_setup_link_policy(struct hci_dev *hdev)
623{
624 u16 link_policy = 0;
625
626 if (hdev->features[0] & LMP_RSWITCH)
627 link_policy |= HCI_LP_RSWITCH;
628 if (hdev->features[0] & LMP_HOLD)
629 link_policy |= HCI_LP_HOLD;
630 if (hdev->features[0] & LMP_SNIFF)
631 link_policy |= HCI_LP_SNIFF;
632 if (hdev->features[1] & LMP_PARK)
633 link_policy |= HCI_LP_PARK;
634
635 link_policy = cpu_to_le16(link_policy);
636 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
637 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200638}
639
640static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
641{
642 struct hci_rp_read_local_commands *rp = (void *) skb->data;
643
644 BT_DBG("%s status 0x%x", hdev->name, rp->status);
645
646 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200647 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200648
649 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200650
651 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
652 hci_setup_link_policy(hdev);
653
654done:
655 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200656}
657
658static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
659{
660 struct hci_rp_read_local_features *rp = (void *) skb->data;
661
662 BT_DBG("%s status 0x%x", hdev->name, rp->status);
663
664 if (rp->status)
665 return;
666
667 memcpy(hdev->features, rp->features, 8);
668
669 /* Adjust default settings according to features
670 * supported by device. */
671
672 if (hdev->features[0] & LMP_3SLOT)
673 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
674
675 if (hdev->features[0] & LMP_5SLOT)
676 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
677
678 if (hdev->features[1] & LMP_HV2) {
679 hdev->pkt_type |= (HCI_HV2);
680 hdev->esco_type |= (ESCO_HV2);
681 }
682
683 if (hdev->features[1] & LMP_HV3) {
684 hdev->pkt_type |= (HCI_HV3);
685 hdev->esco_type |= (ESCO_HV3);
686 }
687
688 if (hdev->features[3] & LMP_ESCO)
689 hdev->esco_type |= (ESCO_EV3);
690
691 if (hdev->features[4] & LMP_EV4)
692 hdev->esco_type |= (ESCO_EV4);
693
694 if (hdev->features[4] & LMP_EV5)
695 hdev->esco_type |= (ESCO_EV5);
696
Marcel Holtmannefc76882009-02-06 09:13:37 +0100697 if (hdev->features[5] & LMP_EDR_ESCO_2M)
698 hdev->esco_type |= (ESCO_2EV3);
699
700 if (hdev->features[5] & LMP_EDR_ESCO_3M)
701 hdev->esco_type |= (ESCO_3EV3);
702
703 if (hdev->features[5] & LMP_EDR_3S_ESCO)
704 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
705
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200706 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
707 hdev->features[0], hdev->features[1],
708 hdev->features[2], hdev->features[3],
709 hdev->features[4], hdev->features[5],
710 hdev->features[6], hdev->features[7]);
711}
712
Andre Guedes971e3a42011-06-30 19:20:52 -0300713static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
714 struct sk_buff *skb)
715{
716 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
717
718 BT_DBG("%s status 0x%x", hdev->name, rp->status);
719
720 if (rp->status)
721 return;
722
Andre Guedesb5b32b62011-12-30 10:34:04 -0300723 switch (rp->page) {
724 case 0:
725 memcpy(hdev->features, rp->features, 8);
726 break;
727 case 1:
728 memcpy(hdev->host_features, rp->features, 8);
729 break;
730 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300731
732 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
733}
734
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200735static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
736 struct sk_buff *skb)
737{
738 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
739
740 BT_DBG("%s status 0x%x", hdev->name, rp->status);
741
742 if (rp->status)
743 return;
744
745 hdev->flow_ctl_mode = rp->mode;
746
747 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
748}
749
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200750static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
751{
752 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
753
754 BT_DBG("%s status 0x%x", hdev->name, rp->status);
755
756 if (rp->status)
757 return;
758
759 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
760 hdev->sco_mtu = rp->sco_mtu;
761 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
762 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
763
764 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
765 hdev->sco_mtu = 64;
766 hdev->sco_pkts = 8;
767 }
768
769 hdev->acl_cnt = hdev->acl_pkts;
770 hdev->sco_cnt = hdev->sco_pkts;
771
772 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
773 hdev->acl_mtu, hdev->acl_pkts,
774 hdev->sco_mtu, hdev->sco_pkts);
775}
776
777static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
778{
779 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
780
781 BT_DBG("%s status 0x%x", hdev->name, rp->status);
782
783 if (!rp->status)
784 bacpy(&hdev->bdaddr, &rp->bdaddr);
785
Johan Hedberg23bb5762010-12-21 23:01:27 +0200786 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
787}
788
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200789static void hci_cc_read_data_block_size(struct hci_dev *hdev,
790 struct sk_buff *skb)
791{
792 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
793
794 BT_DBG("%s status 0x%x", hdev->name, rp->status);
795
796 if (rp->status)
797 return;
798
799 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
800 hdev->block_len = __le16_to_cpu(rp->block_len);
801 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
802
803 hdev->block_cnt = hdev->num_blocks;
804
805 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
806 hdev->block_cnt, hdev->block_len);
807
808 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
809}
810
Johan Hedberg23bb5762010-12-21 23:01:27 +0200811static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
812{
813 __u8 status = *((__u8 *) skb->data);
814
815 BT_DBG("%s status 0x%x", hdev->name, status);
816
817 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200818}
819
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300820static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
821 struct sk_buff *skb)
822{
823 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
824
825 BT_DBG("%s status 0x%x", hdev->name, rp->status);
826
827 if (rp->status)
828 return;
829
830 hdev->amp_status = rp->amp_status;
831 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
832 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
833 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
834 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
835 hdev->amp_type = rp->amp_type;
836 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
837 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
838 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
839 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
840
841 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
842}
843
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200844static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
845 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_DELETE_STORED_LINK_KEY, status);
852}
853
Johan Hedbergd5859e22011-01-25 01:19:58 +0200854static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
855{
856 __u8 status = *((__u8 *) skb->data);
857
858 BT_DBG("%s status 0x%x", hdev->name, status);
859
860 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
861}
862
863static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
864 struct sk_buff *skb)
865{
866 __u8 status = *((__u8 *) skb->data);
867
868 BT_DBG("%s status 0x%x", hdev->name, status);
869
870 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
871}
872
873static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
874 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_READ_INQ_RSP_TX_POWER, status);
881}
882
883static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
884{
885 __u8 status = *((__u8 *) skb->data);
886
887 BT_DBG("%s status 0x%x", hdev->name, status);
888
889 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
890}
891
Johan Hedberg980e1a52011-01-22 06:10:07 +0200892static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
893{
894 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
895 struct hci_cp_pin_code_reply *cp;
896 struct hci_conn *conn;
897
898 BT_DBG("%s status 0x%x", hdev->name, rp->status);
899
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200900 hci_dev_lock(hdev);
901
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200902 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200903 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200904
905 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200906 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200907
908 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
909 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200910 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200911
912 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
913 if (conn)
914 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200915
916unlock:
917 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200918}
919
920static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
921{
922 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
923
924 BT_DBG("%s status 0x%x", hdev->name, rp->status);
925
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200926 hci_dev_lock(hdev);
927
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200928 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200929 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200930 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200931
932 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200933}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200934
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300935static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
936 struct sk_buff *skb)
937{
938 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
939
940 BT_DBG("%s status 0x%x", hdev->name, rp->status);
941
942 if (rp->status)
943 return;
944
945 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
946 hdev->le_pkts = rp->le_max_pkt;
947
948 hdev->le_cnt = hdev->le_pkts;
949
950 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
951
952 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
953}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200954
Johan Hedberga5c29682011-02-19 12:05:57 -0300955static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
956{
957 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
958
959 BT_DBG("%s status 0x%x", hdev->name, rp->status);
960
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200961 hci_dev_lock(hdev);
962
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200963 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200964 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
965 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200966
967 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300968}
969
970static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
971 struct sk_buff *skb)
972{
973 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
974
975 BT_DBG("%s status 0x%x", hdev->name, rp->status);
976
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200977 hci_dev_lock(hdev);
978
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200979 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200980 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200981 ACL_LINK, 0,
Johan Hedberga5c29682011-02-19 12:05:57 -0300982 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200983
984 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300985}
986
Brian Gix1143d452011-11-23 08:28:34 -0800987static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
988{
989 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
990
991 BT_DBG("%s status 0x%x", hdev->name, rp->status);
992
993 hci_dev_lock(hdev);
994
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200995 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200996 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
997 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800998
999 hci_dev_unlock(hdev);
1000}
1001
1002static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1003 struct sk_buff *skb)
1004{
1005 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1006
1007 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1008
1009 hci_dev_lock(hdev);
1010
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001011 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001012 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001013 ACL_LINK, 0,
Brian Gix1143d452011-11-23 08:28:34 -08001014 rp->status);
1015
1016 hci_dev_unlock(hdev);
1017}
1018
Szymon Jancc35938b2011-03-22 13:12:21 +01001019static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1020 struct sk_buff *skb)
1021{
1022 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1023
1024 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1025
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001026 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001027 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001028 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001029 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001030}
1031
Andre Guedes07f7fa52011-12-02 21:13:31 +09001032static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1033{
1034 __u8 status = *((__u8 *) skb->data);
1035
1036 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001037
1038 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001039
1040 if (status) {
1041 hci_dev_lock(hdev);
1042 mgmt_start_discovery_failed(hdev, status);
1043 hci_dev_unlock(hdev);
1044 return;
1045 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001046}
1047
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001048static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1049 struct sk_buff *skb)
1050{
1051 struct hci_cp_le_set_scan_enable *cp;
1052 __u8 status = *((__u8 *) skb->data);
1053
1054 BT_DBG("%s status 0x%x", hdev->name, status);
1055
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001056 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1057 if (!cp)
1058 return;
1059
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001060 switch (cp->enable) {
1061 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001062 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1063
Andre Guedes3fd24152012-02-03 17:48:01 -03001064 if (status) {
1065 hci_dev_lock(hdev);
1066 mgmt_start_discovery_failed(hdev, status);
1067 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001068 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001069 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001070
Andre Guedesd23264a2011-11-25 20:53:38 -03001071 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1072
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001073 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001074
1075 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001076 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001077 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001078 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001079 break;
1080
1081 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001082 if (status)
1083 return;
1084
Andre Guedesd23264a2011-11-25 20:53:38 -03001085 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1086
Andre Guedesd0843292012-01-02 19:18:11 -03001087 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001088
1089 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1090 mgmt_interleaved_discovery(hdev);
1091 } else {
1092 hci_dev_lock(hdev);
1093 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1094 hci_dev_unlock(hdev);
1095 }
1096
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001097 break;
1098
1099 default:
1100 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1101 break;
Andre Guedes35815082011-05-26 16:23:53 -03001102 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001103}
1104
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001105static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1106{
1107 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1108
1109 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1110
1111 if (rp->status)
1112 return;
1113
1114 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1115}
1116
1117static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1118{
1119 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1120
1121 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1122
1123 if (rp->status)
1124 return;
1125
1126 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1127}
1128
Andre Guedesf9b49302011-06-30 19:20:53 -03001129static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1130 struct sk_buff *skb)
1131{
1132 struct hci_cp_read_local_ext_features cp;
Johan Hedberg06199cf2012-02-22 16:37:11 +02001133 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001134 __u8 status = *((__u8 *) skb->data);
1135
1136 BT_DBG("%s status 0x%x", hdev->name, status);
1137
Johan Hedberg06199cf2012-02-22 16:37:11 +02001138 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
1139 if (sent && test_bit(HCI_MGMT, &hdev->dev_flags))
1140 mgmt_le_enable_complete(hdev, sent->le, status);
1141
Andre Guedesf9b49302011-06-30 19:20:53 -03001142 if (status)
1143 return;
1144
1145 cp.page = 0x01;
1146 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1147}
1148
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001149static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1150{
1151 BT_DBG("%s status 0x%x", hdev->name, status);
1152
1153 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001154 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001155 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001156 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001157 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001158 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001159 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001160 return;
1161 }
1162
Andre Guedes89352e72011-11-04 14:16:53 -03001163 set_bit(HCI_INQUIRY, &hdev->flags);
1164
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001165 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001166 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001167 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001168}
1169
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1171{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001172 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001175 BT_DBG("%s status 0x%x", hdev->name, status);
1176
1177 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 if (!cp)
1179 return;
1180
1181 hci_dev_lock(hdev);
1182
1183 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1184
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001185 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186
1187 if (status) {
1188 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001189 if (status != 0x0c || conn->attempt > 2) {
1190 conn->state = BT_CLOSED;
1191 hci_proto_connect_cfm(conn, status);
1192 hci_conn_del(conn);
1193 } else
1194 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 }
1196 } else {
1197 if (!conn) {
1198 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1199 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001200 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201 conn->link_mode |= HCI_LM_MASTER;
1202 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001203 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 }
1205 }
1206
1207 hci_dev_unlock(hdev);
1208}
1209
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001210static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001212 struct hci_cp_add_sco *cp;
1213 struct hci_conn *acl, *sco;
1214 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001216 BT_DBG("%s status 0x%x", hdev->name, status);
1217
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001218 if (!status)
1219 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001221 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1222 if (!cp)
1223 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001225 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001227 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001228
1229 hci_dev_lock(hdev);
1230
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001231 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001232 if (acl) {
1233 sco = acl->link;
1234 if (sco) {
1235 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001236
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001237 hci_proto_connect_cfm(sco, status);
1238 hci_conn_del(sco);
1239 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001240 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001241
1242 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243}
1244
Marcel Holtmannf8558552008-07-14 20:13:49 +02001245static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1246{
1247 struct hci_cp_auth_requested *cp;
1248 struct hci_conn *conn;
1249
1250 BT_DBG("%s status 0x%x", hdev->name, status);
1251
1252 if (!status)
1253 return;
1254
1255 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1256 if (!cp)
1257 return;
1258
1259 hci_dev_lock(hdev);
1260
1261 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1262 if (conn) {
1263 if (conn->state == BT_CONFIG) {
1264 hci_proto_connect_cfm(conn, status);
1265 hci_conn_put(conn);
1266 }
1267 }
1268
1269 hci_dev_unlock(hdev);
1270}
1271
1272static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1273{
1274 struct hci_cp_set_conn_encrypt *cp;
1275 struct hci_conn *conn;
1276
1277 BT_DBG("%s status 0x%x", hdev->name, status);
1278
1279 if (!status)
1280 return;
1281
1282 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1283 if (!cp)
1284 return;
1285
1286 hci_dev_lock(hdev);
1287
1288 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1289 if (conn) {
1290 if (conn->state == BT_CONFIG) {
1291 hci_proto_connect_cfm(conn, status);
1292 hci_conn_put(conn);
1293 }
1294 }
1295
1296 hci_dev_unlock(hdev);
1297}
1298
Johan Hedberg127178d2010-11-18 22:22:29 +02001299static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001300 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001301{
Johan Hedberg392599b2010-11-18 22:22:28 +02001302 if (conn->state != BT_CONFIG || !conn->out)
1303 return 0;
1304
Johan Hedberg765c2a92011-01-19 12:06:52 +05301305 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001306 return 0;
1307
1308 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001309 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001310 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001311 conn->pending_sec_level != BT_SECURITY_HIGH &&
1312 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001313 return 0;
1314
Johan Hedberg392599b2010-11-18 22:22:28 +02001315 return 1;
1316}
1317
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001318static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1319{
1320 struct hci_cp_remote_name_req cp;
1321
1322 memset(&cp, 0, sizeof(cp));
1323
1324 bacpy(&cp.bdaddr, &e->data.bdaddr);
1325 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1326 cp.pscan_mode = e->data.pscan_mode;
1327 cp.clock_offset = e->data.clock_offset;
1328
1329 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1330}
1331
Johan Hedbergb644ba32012-01-17 21:48:47 +02001332static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001333{
1334 struct discovery_state *discov = &hdev->discovery;
1335 struct inquiry_entry *e;
1336
Johan Hedbergb644ba32012-01-17 21:48:47 +02001337 if (list_empty(&discov->resolve))
1338 return false;
1339
1340 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1341 if (hci_resolve_name(hdev, e) == 0) {
1342 e->name_state = NAME_PENDING;
1343 return true;
1344 }
1345
1346 return false;
1347}
1348
1349static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1350 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1351{
1352 struct discovery_state *discov = &hdev->discovery;
1353 struct inquiry_entry *e;
1354
1355 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1356 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
1357 name, name_len, conn->dev_class);
1358
1359 if (discov->state == DISCOVERY_STOPPED)
1360 return;
1361
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001362 if (discov->state == DISCOVERY_STOPPING)
1363 goto discov_complete;
1364
1365 if (discov->state != DISCOVERY_RESOLVING)
1366 return;
1367
1368 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1369 if (e) {
1370 e->name_state = NAME_KNOWN;
1371 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001372 if (name)
1373 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1374 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001375 }
1376
Johan Hedbergb644ba32012-01-17 21:48:47 +02001377 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001378 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001379
1380discov_complete:
1381 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1382}
1383
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001384static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1385{
Johan Hedberg127178d2010-11-18 22:22:29 +02001386 struct hci_cp_remote_name_req *cp;
1387 struct hci_conn *conn;
1388
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001389 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001390
1391 /* If successful wait for the name req complete event before
1392 * checking for the need to do authentication */
1393 if (!status)
1394 return;
1395
1396 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1397 if (!cp)
1398 return;
1399
1400 hci_dev_lock(hdev);
1401
1402 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001403
1404 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1405 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1406
Johan Hedberg79c6c702011-04-28 11:28:55 -07001407 if (!conn)
1408 goto unlock;
1409
1410 if (!hci_outgoing_auth_needed(hdev, conn))
1411 goto unlock;
1412
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001413 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001414 struct hci_cp_auth_requested cp;
1415 cp.handle = __cpu_to_le16(conn->handle);
1416 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1417 }
1418
Johan Hedberg79c6c702011-04-28 11:28:55 -07001419unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001420 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001421}
1422
Marcel Holtmann769be972008-07-14 20:13:49 +02001423static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1424{
1425 struct hci_cp_read_remote_features *cp;
1426 struct hci_conn *conn;
1427
1428 BT_DBG("%s status 0x%x", hdev->name, status);
1429
1430 if (!status)
1431 return;
1432
1433 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1434 if (!cp)
1435 return;
1436
1437 hci_dev_lock(hdev);
1438
1439 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1440 if (conn) {
1441 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001442 hci_proto_connect_cfm(conn, status);
1443 hci_conn_put(conn);
1444 }
1445 }
1446
1447 hci_dev_unlock(hdev);
1448}
1449
1450static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1451{
1452 struct hci_cp_read_remote_ext_features *cp;
1453 struct hci_conn *conn;
1454
1455 BT_DBG("%s status 0x%x", hdev->name, status);
1456
1457 if (!status)
1458 return;
1459
1460 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1461 if (!cp)
1462 return;
1463
1464 hci_dev_lock(hdev);
1465
1466 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1467 if (conn) {
1468 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001469 hci_proto_connect_cfm(conn, status);
1470 hci_conn_put(conn);
1471 }
1472 }
1473
1474 hci_dev_unlock(hdev);
1475}
1476
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001477static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1478{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001479 struct hci_cp_setup_sync_conn *cp;
1480 struct hci_conn *acl, *sco;
1481 __u16 handle;
1482
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001483 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001484
1485 if (!status)
1486 return;
1487
1488 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1489 if (!cp)
1490 return;
1491
1492 handle = __le16_to_cpu(cp->handle);
1493
1494 BT_DBG("%s handle %d", hdev->name, handle);
1495
1496 hci_dev_lock(hdev);
1497
1498 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001499 if (acl) {
1500 sco = acl->link;
1501 if (sco) {
1502 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001503
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001504 hci_proto_connect_cfm(sco, status);
1505 hci_conn_del(sco);
1506 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001507 }
1508
1509 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001510}
1511
1512static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1513{
1514 struct hci_cp_sniff_mode *cp;
1515 struct hci_conn *conn;
1516
1517 BT_DBG("%s status 0x%x", hdev->name, status);
1518
1519 if (!status)
1520 return;
1521
1522 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1523 if (!cp)
1524 return;
1525
1526 hci_dev_lock(hdev);
1527
1528 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001529 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001530 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001531
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001532 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001533 hci_sco_setup(conn, status);
1534 }
1535
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001536 hci_dev_unlock(hdev);
1537}
1538
1539static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1540{
1541 struct hci_cp_exit_sniff_mode *cp;
1542 struct hci_conn *conn;
1543
1544 BT_DBG("%s status 0x%x", hdev->name, status);
1545
1546 if (!status)
1547 return;
1548
1549 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1550 if (!cp)
1551 return;
1552
1553 hci_dev_lock(hdev);
1554
1555 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001556 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001557 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001558
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001559 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001560 hci_sco_setup(conn, status);
1561 }
1562
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001563 hci_dev_unlock(hdev);
1564}
1565
Johan Hedberg88c3df12012-02-09 14:27:38 +02001566static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1567{
1568 struct hci_cp_disconnect *cp;
1569 struct hci_conn *conn;
1570
1571 if (!status)
1572 return;
1573
1574 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1575 if (!cp)
1576 return;
1577
1578 hci_dev_lock(hdev);
1579
1580 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1581 if (conn)
1582 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1583 conn->dst_type, status);
1584
1585 hci_dev_unlock(hdev);
1586}
1587
Ville Tervofcd89c02011-02-10 22:38:47 -03001588static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1589{
1590 struct hci_cp_le_create_conn *cp;
1591 struct hci_conn *conn;
1592
1593 BT_DBG("%s status 0x%x", hdev->name, status);
1594
1595 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1596 if (!cp)
1597 return;
1598
1599 hci_dev_lock(hdev);
1600
1601 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1602
1603 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1604 conn);
1605
1606 if (status) {
1607 if (conn && conn->state == BT_CONNECT) {
1608 conn->state = BT_CLOSED;
1609 hci_proto_connect_cfm(conn, status);
1610 hci_conn_del(conn);
1611 }
1612 } else {
1613 if (!conn) {
1614 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001615 if (conn) {
1616 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001617 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001618 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001619 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001620 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001621 }
1622 }
1623
1624 hci_dev_unlock(hdev);
1625}
1626
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001627static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1628{
1629 BT_DBG("%s status 0x%x", hdev->name, status);
1630}
1631
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001632static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1633{
1634 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001635 struct discovery_state *discov = &hdev->discovery;
1636 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001637
1638 BT_DBG("%s status %d", hdev->name, status);
1639
Johan Hedberg23bb5762010-12-21 23:01:27 +02001640 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001641
1642 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001643
1644 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1645 return;
1646
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001647 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001648 return;
1649
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001650 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001651
Andre Guedes343f9352012-02-17 20:39:37 -03001652 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001653 goto unlock;
1654
1655 if (list_empty(&discov->resolve)) {
1656 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1657 goto unlock;
1658 }
1659
1660 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1661 if (e && hci_resolve_name(hdev, e) == 0) {
1662 e->name_state = NAME_PENDING;
1663 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1664 } else {
1665 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1666 }
1667
1668unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001669 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001670}
1671
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1673{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001674 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001675 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 int num_rsp = *((__u8 *) skb->data);
1677
1678 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1679
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001680 if (!num_rsp)
1681 return;
1682
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001684
Johan Hedberge17acd42011-03-30 23:57:16 +03001685 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg31754052012-01-04 13:39:52 +02001686 bool name_known;
1687
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 bacpy(&data.bdaddr, &info->bdaddr);
1689 data.pscan_rep_mode = info->pscan_rep_mode;
1690 data.pscan_period_mode = info->pscan_period_mode;
1691 data.pscan_mode = info->pscan_mode;
1692 memcpy(data.dev_class, info->dev_class, 3);
1693 data.clock_offset = info->clock_offset;
1694 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001695 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001696
1697 name_known = hci_inquiry_cache_update(hdev, &data, false);
Johan Hedberg48264f02011-11-09 13:58:58 +02001698 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Andre Guedes7d262f82012-01-10 18:20:49 -03001699 info->dev_class, 0, !name_known,
1700 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001702
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 hci_dev_unlock(hdev);
1704}
1705
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001706static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001708 struct hci_ev_conn_complete *ev = (void *) skb->data;
1709 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001711 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001712
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001714
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001715 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001716 if (!conn) {
1717 if (ev->link_type != SCO_LINK)
1718 goto unlock;
1719
1720 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1721 if (!conn)
1722 goto unlock;
1723
1724 conn->type = SCO_LINK;
1725 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001726
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001727 if (!ev->status) {
1728 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001729
1730 if (conn->type == ACL_LINK) {
1731 conn->state = BT_CONFIG;
1732 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001733 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001734 } else
1735 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001736
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001737 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001738 hci_conn_add_sysfs(conn);
1739
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001740 if (test_bit(HCI_AUTH, &hdev->flags))
1741 conn->link_mode |= HCI_LM_AUTH;
1742
1743 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1744 conn->link_mode |= HCI_LM_ENCRYPT;
1745
1746 /* Get remote features */
1747 if (conn->type == ACL_LINK) {
1748 struct hci_cp_read_remote_features cp;
1749 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001750 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1751 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001752 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001753
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001754 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001755 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001756 struct hci_cp_change_conn_ptype cp;
1757 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001758 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1759 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1760 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001761 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001762 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001763 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001764 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001765 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001766 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001767 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001768
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001769 if (conn->type == ACL_LINK)
1770 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001771
Marcel Holtmann769be972008-07-14 20:13:49 +02001772 if (ev->status) {
1773 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001774 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001775 } else if (ev->link_type != ACL_LINK)
1776 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001777
1778unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001780
1781 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782}
1783
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1785{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001786 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 int mask = hdev->link_mode;
1788
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001789 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1790 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791
1792 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1793
Szymon Janc138d22e2011-02-17 16:44:23 +01001794 if ((mask & HCI_LM_ACCEPT) &&
1795 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001797 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799
1800 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001801
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001802 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1803 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001804 memcpy(ie->data.dev_class, ev->dev_class, 3);
1805
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1807 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001808 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1809 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001810 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 hci_dev_unlock(hdev);
1812 return;
1813 }
1814 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001815
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 memcpy(conn->dev_class, ev->dev_class, 3);
1817 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001818
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 hci_dev_unlock(hdev);
1820
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001821 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1822 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001824 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001826 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1827 cp.role = 0x00; /* Become master */
1828 else
1829 cp.role = 0x01; /* Remain slave */
1830
1831 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1832 sizeof(cp), &cp);
1833 } else {
1834 struct hci_cp_accept_sync_conn_req cp;
1835
1836 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001837 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001838
1839 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1840 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1841 cp.max_latency = cpu_to_le16(0xffff);
1842 cp.content_format = cpu_to_le16(hdev->voice_setting);
1843 cp.retrans_effort = 0xff;
1844
1845 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1846 sizeof(cp), &cp);
1847 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 } else {
1849 /* Connection rejected */
1850 struct hci_cp_reject_conn_req cp;
1851
1852 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001853 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001854 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855 }
1856}
1857
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1859{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001860 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001861 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
1863 BT_DBG("%s status %d", hdev->name, ev->status);
1864
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 hci_dev_lock(hdev);
1866
Marcel Holtmann04837f62006-07-03 10:02:33 +02001867 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001868 if (!conn)
1869 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001870
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001871 if (ev->status == 0)
1872 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
Johan Hedbergb644ba32012-01-17 21:48:47 +02001874 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1875 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001876 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001877 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1878 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001879 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001880 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001881 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001882 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001883
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001884 if (ev->status == 0) {
1885 hci_proto_disconn_cfm(conn, ev->reason);
1886 hci_conn_del(conn);
1887 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001888
1889unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 hci_dev_unlock(hdev);
1891}
1892
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001893static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1894{
1895 struct hci_ev_auth_complete *ev = (void *) skb->data;
1896 struct hci_conn *conn;
1897
1898 BT_DBG("%s status %d", hdev->name, ev->status);
1899
1900 hci_dev_lock(hdev);
1901
1902 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001903 if (!conn)
1904 goto unlock;
1905
1906 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001907 if (!hci_conn_ssp_enabled(conn) &&
1908 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001909 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001910 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001911 conn->link_mode |= HCI_LM_AUTH;
1912 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001913 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001914 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001915 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
1916 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001917 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001918
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001919 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1920 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001921
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001922 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001923 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001924 struct hci_cp_set_conn_encrypt cp;
1925 cp.handle = ev->handle;
1926 cp.encrypt = 0x01;
1927 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1928 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001929 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001930 conn->state = BT_CONNECTED;
1931 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001932 hci_conn_put(conn);
1933 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001934 } else {
1935 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001936
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001937 hci_conn_hold(conn);
1938 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1939 hci_conn_put(conn);
1940 }
1941
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001942 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001943 if (!ev->status) {
1944 struct hci_cp_set_conn_encrypt cp;
1945 cp.handle = ev->handle;
1946 cp.encrypt = 0x01;
1947 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1948 &cp);
1949 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001950 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001951 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001952 }
1953 }
1954
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001955unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001956 hci_dev_unlock(hdev);
1957}
1958
1959static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1960{
Johan Hedberg127178d2010-11-18 22:22:29 +02001961 struct hci_ev_remote_name *ev = (void *) skb->data;
1962 struct hci_conn *conn;
1963
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001964 BT_DBG("%s", hdev->name);
1965
1966 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001967
1968 hci_dev_lock(hdev);
1969
1970 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001971
1972 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1973 goto check_auth;
1974
1975 if (ev->status == 0)
1976 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1977 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1978 else
1979 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1980
1981check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001982 if (!conn)
1983 goto unlock;
1984
1985 if (!hci_outgoing_auth_needed(hdev, conn))
1986 goto unlock;
1987
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001988 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001989 struct hci_cp_auth_requested cp;
1990 cp.handle = __cpu_to_le16(conn->handle);
1991 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1992 }
1993
Johan Hedberg79c6c702011-04-28 11:28:55 -07001994unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001995 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001996}
1997
1998static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1999{
2000 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2001 struct hci_conn *conn;
2002
2003 BT_DBG("%s status %d", hdev->name, ev->status);
2004
2005 hci_dev_lock(hdev);
2006
2007 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2008 if (conn) {
2009 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002010 if (ev->encrypt) {
2011 /* Encryption implies authentication */
2012 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002013 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002014 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002015 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002016 conn->link_mode &= ~HCI_LM_ENCRYPT;
2017 }
2018
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002019 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002020
Marcel Holtmannf8558552008-07-14 20:13:49 +02002021 if (conn->state == BT_CONFIG) {
2022 if (!ev->status)
2023 conn->state = BT_CONNECTED;
2024
2025 hci_proto_connect_cfm(conn, ev->status);
2026 hci_conn_put(conn);
2027 } else
2028 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002029 }
2030
2031 hci_dev_unlock(hdev);
2032}
2033
2034static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2035{
2036 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2037 struct hci_conn *conn;
2038
2039 BT_DBG("%s status %d", hdev->name, ev->status);
2040
2041 hci_dev_lock(hdev);
2042
2043 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2044 if (conn) {
2045 if (!ev->status)
2046 conn->link_mode |= HCI_LM_SECURE;
2047
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002048 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002049
2050 hci_key_change_cfm(conn, ev->status);
2051 }
2052
2053 hci_dev_unlock(hdev);
2054}
2055
2056static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2057{
2058 struct hci_ev_remote_features *ev = (void *) skb->data;
2059 struct hci_conn *conn;
2060
2061 BT_DBG("%s status %d", hdev->name, ev->status);
2062
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002063 hci_dev_lock(hdev);
2064
2065 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002066 if (!conn)
2067 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002068
Johan Hedbergccd556f2010-11-10 17:11:51 +02002069 if (!ev->status)
2070 memcpy(conn->features, ev->features, 8);
2071
2072 if (conn->state != BT_CONFIG)
2073 goto unlock;
2074
2075 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2076 struct hci_cp_read_remote_ext_features cp;
2077 cp.handle = ev->handle;
2078 cp.page = 0x01;
2079 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002080 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002081 goto unlock;
2082 }
2083
Johan Hedberg127178d2010-11-18 22:22:29 +02002084 if (!ev->status) {
2085 struct hci_cp_remote_name_req cp;
2086 memset(&cp, 0, sizeof(cp));
2087 bacpy(&cp.bdaddr, &conn->dst);
2088 cp.pscan_rep_mode = 0x02;
2089 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002090 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2091 mgmt_device_connected(hdev, &conn->dst, conn->type,
2092 conn->dst_type, NULL, 0,
2093 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002094
Johan Hedberg127178d2010-11-18 22:22:29 +02002095 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002096 conn->state = BT_CONNECTED;
2097 hci_proto_connect_cfm(conn, ev->status);
2098 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002099 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002100
Johan Hedbergccd556f2010-11-10 17:11:51 +02002101unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002102 hci_dev_unlock(hdev);
2103}
2104
2105static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2106{
2107 BT_DBG("%s", hdev->name);
2108}
2109
2110static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2111{
2112 BT_DBG("%s", hdev->name);
2113}
2114
2115static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2116{
2117 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2118 __u16 opcode;
2119
2120 skb_pull(skb, sizeof(*ev));
2121
2122 opcode = __le16_to_cpu(ev->opcode);
2123
2124 switch (opcode) {
2125 case HCI_OP_INQUIRY_CANCEL:
2126 hci_cc_inquiry_cancel(hdev, skb);
2127 break;
2128
2129 case HCI_OP_EXIT_PERIODIC_INQ:
2130 hci_cc_exit_periodic_inq(hdev, skb);
2131 break;
2132
2133 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2134 hci_cc_remote_name_req_cancel(hdev, skb);
2135 break;
2136
2137 case HCI_OP_ROLE_DISCOVERY:
2138 hci_cc_role_discovery(hdev, skb);
2139 break;
2140
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002141 case HCI_OP_READ_LINK_POLICY:
2142 hci_cc_read_link_policy(hdev, skb);
2143 break;
2144
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002145 case HCI_OP_WRITE_LINK_POLICY:
2146 hci_cc_write_link_policy(hdev, skb);
2147 break;
2148
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002149 case HCI_OP_READ_DEF_LINK_POLICY:
2150 hci_cc_read_def_link_policy(hdev, skb);
2151 break;
2152
2153 case HCI_OP_WRITE_DEF_LINK_POLICY:
2154 hci_cc_write_def_link_policy(hdev, skb);
2155 break;
2156
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002157 case HCI_OP_RESET:
2158 hci_cc_reset(hdev, skb);
2159 break;
2160
2161 case HCI_OP_WRITE_LOCAL_NAME:
2162 hci_cc_write_local_name(hdev, skb);
2163 break;
2164
2165 case HCI_OP_READ_LOCAL_NAME:
2166 hci_cc_read_local_name(hdev, skb);
2167 break;
2168
2169 case HCI_OP_WRITE_AUTH_ENABLE:
2170 hci_cc_write_auth_enable(hdev, skb);
2171 break;
2172
2173 case HCI_OP_WRITE_ENCRYPT_MODE:
2174 hci_cc_write_encrypt_mode(hdev, skb);
2175 break;
2176
2177 case HCI_OP_WRITE_SCAN_ENABLE:
2178 hci_cc_write_scan_enable(hdev, skb);
2179 break;
2180
2181 case HCI_OP_READ_CLASS_OF_DEV:
2182 hci_cc_read_class_of_dev(hdev, skb);
2183 break;
2184
2185 case HCI_OP_WRITE_CLASS_OF_DEV:
2186 hci_cc_write_class_of_dev(hdev, skb);
2187 break;
2188
2189 case HCI_OP_READ_VOICE_SETTING:
2190 hci_cc_read_voice_setting(hdev, skb);
2191 break;
2192
2193 case HCI_OP_WRITE_VOICE_SETTING:
2194 hci_cc_write_voice_setting(hdev, skb);
2195 break;
2196
2197 case HCI_OP_HOST_BUFFER_SIZE:
2198 hci_cc_host_buffer_size(hdev, skb);
2199 break;
2200
Marcel Holtmann333140b2008-07-14 20:13:48 +02002201 case HCI_OP_WRITE_SSP_MODE:
2202 hci_cc_write_ssp_mode(hdev, skb);
2203 break;
2204
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002205 case HCI_OP_READ_LOCAL_VERSION:
2206 hci_cc_read_local_version(hdev, skb);
2207 break;
2208
2209 case HCI_OP_READ_LOCAL_COMMANDS:
2210 hci_cc_read_local_commands(hdev, skb);
2211 break;
2212
2213 case HCI_OP_READ_LOCAL_FEATURES:
2214 hci_cc_read_local_features(hdev, skb);
2215 break;
2216
Andre Guedes971e3a42011-06-30 19:20:52 -03002217 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2218 hci_cc_read_local_ext_features(hdev, skb);
2219 break;
2220
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002221 case HCI_OP_READ_BUFFER_SIZE:
2222 hci_cc_read_buffer_size(hdev, skb);
2223 break;
2224
2225 case HCI_OP_READ_BD_ADDR:
2226 hci_cc_read_bd_addr(hdev, skb);
2227 break;
2228
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002229 case HCI_OP_READ_DATA_BLOCK_SIZE:
2230 hci_cc_read_data_block_size(hdev, skb);
2231 break;
2232
Johan Hedberg23bb5762010-12-21 23:01:27 +02002233 case HCI_OP_WRITE_CA_TIMEOUT:
2234 hci_cc_write_ca_timeout(hdev, skb);
2235 break;
2236
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002237 case HCI_OP_READ_FLOW_CONTROL_MODE:
2238 hci_cc_read_flow_control_mode(hdev, skb);
2239 break;
2240
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002241 case HCI_OP_READ_LOCAL_AMP_INFO:
2242 hci_cc_read_local_amp_info(hdev, skb);
2243 break;
2244
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002245 case HCI_OP_DELETE_STORED_LINK_KEY:
2246 hci_cc_delete_stored_link_key(hdev, skb);
2247 break;
2248
Johan Hedbergd5859e22011-01-25 01:19:58 +02002249 case HCI_OP_SET_EVENT_MASK:
2250 hci_cc_set_event_mask(hdev, skb);
2251 break;
2252
2253 case HCI_OP_WRITE_INQUIRY_MODE:
2254 hci_cc_write_inquiry_mode(hdev, skb);
2255 break;
2256
2257 case HCI_OP_READ_INQ_RSP_TX_POWER:
2258 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2259 break;
2260
2261 case HCI_OP_SET_EVENT_FLT:
2262 hci_cc_set_event_flt(hdev, skb);
2263 break;
2264
Johan Hedberg980e1a52011-01-22 06:10:07 +02002265 case HCI_OP_PIN_CODE_REPLY:
2266 hci_cc_pin_code_reply(hdev, skb);
2267 break;
2268
2269 case HCI_OP_PIN_CODE_NEG_REPLY:
2270 hci_cc_pin_code_neg_reply(hdev, skb);
2271 break;
2272
Szymon Jancc35938b2011-03-22 13:12:21 +01002273 case HCI_OP_READ_LOCAL_OOB_DATA:
2274 hci_cc_read_local_oob_data_reply(hdev, skb);
2275 break;
2276
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002277 case HCI_OP_LE_READ_BUFFER_SIZE:
2278 hci_cc_le_read_buffer_size(hdev, skb);
2279 break;
2280
Johan Hedberga5c29682011-02-19 12:05:57 -03002281 case HCI_OP_USER_CONFIRM_REPLY:
2282 hci_cc_user_confirm_reply(hdev, skb);
2283 break;
2284
2285 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2286 hci_cc_user_confirm_neg_reply(hdev, skb);
2287 break;
2288
Brian Gix1143d452011-11-23 08:28:34 -08002289 case HCI_OP_USER_PASSKEY_REPLY:
2290 hci_cc_user_passkey_reply(hdev, skb);
2291 break;
2292
2293 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2294 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002295
2296 case HCI_OP_LE_SET_SCAN_PARAM:
2297 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002298 break;
2299
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002300 case HCI_OP_LE_SET_SCAN_ENABLE:
2301 hci_cc_le_set_scan_enable(hdev, skb);
2302 break;
2303
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002304 case HCI_OP_LE_LTK_REPLY:
2305 hci_cc_le_ltk_reply(hdev, skb);
2306 break;
2307
2308 case HCI_OP_LE_LTK_NEG_REPLY:
2309 hci_cc_le_ltk_neg_reply(hdev, skb);
2310 break;
2311
Andre Guedesf9b49302011-06-30 19:20:53 -03002312 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2313 hci_cc_write_le_host_supported(hdev, skb);
2314 break;
2315
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002316 default:
2317 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2318 break;
2319 }
2320
Ville Tervo6bd32322011-02-16 16:32:41 +02002321 if (ev->opcode != HCI_OP_NOP)
2322 del_timer(&hdev->cmd_timer);
2323
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002324 if (ev->ncmd) {
2325 atomic_set(&hdev->cmd_cnt, 1);
2326 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002327 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002328 }
2329}
2330
2331static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2332{
2333 struct hci_ev_cmd_status *ev = (void *) skb->data;
2334 __u16 opcode;
2335
2336 skb_pull(skb, sizeof(*ev));
2337
2338 opcode = __le16_to_cpu(ev->opcode);
2339
2340 switch (opcode) {
2341 case HCI_OP_INQUIRY:
2342 hci_cs_inquiry(hdev, ev->status);
2343 break;
2344
2345 case HCI_OP_CREATE_CONN:
2346 hci_cs_create_conn(hdev, ev->status);
2347 break;
2348
2349 case HCI_OP_ADD_SCO:
2350 hci_cs_add_sco(hdev, ev->status);
2351 break;
2352
Marcel Holtmannf8558552008-07-14 20:13:49 +02002353 case HCI_OP_AUTH_REQUESTED:
2354 hci_cs_auth_requested(hdev, ev->status);
2355 break;
2356
2357 case HCI_OP_SET_CONN_ENCRYPT:
2358 hci_cs_set_conn_encrypt(hdev, ev->status);
2359 break;
2360
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002361 case HCI_OP_REMOTE_NAME_REQ:
2362 hci_cs_remote_name_req(hdev, ev->status);
2363 break;
2364
Marcel Holtmann769be972008-07-14 20:13:49 +02002365 case HCI_OP_READ_REMOTE_FEATURES:
2366 hci_cs_read_remote_features(hdev, ev->status);
2367 break;
2368
2369 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2370 hci_cs_read_remote_ext_features(hdev, ev->status);
2371 break;
2372
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002373 case HCI_OP_SETUP_SYNC_CONN:
2374 hci_cs_setup_sync_conn(hdev, ev->status);
2375 break;
2376
2377 case HCI_OP_SNIFF_MODE:
2378 hci_cs_sniff_mode(hdev, ev->status);
2379 break;
2380
2381 case HCI_OP_EXIT_SNIFF_MODE:
2382 hci_cs_exit_sniff_mode(hdev, ev->status);
2383 break;
2384
Johan Hedberg8962ee72011-01-20 12:40:27 +02002385 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002386 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002387 break;
2388
Ville Tervofcd89c02011-02-10 22:38:47 -03002389 case HCI_OP_LE_CREATE_CONN:
2390 hci_cs_le_create_conn(hdev, ev->status);
2391 break;
2392
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002393 case HCI_OP_LE_START_ENC:
2394 hci_cs_le_start_enc(hdev, ev->status);
2395 break;
2396
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002397 default:
2398 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2399 break;
2400 }
2401
Ville Tervo6bd32322011-02-16 16:32:41 +02002402 if (ev->opcode != HCI_OP_NOP)
2403 del_timer(&hdev->cmd_timer);
2404
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002405 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002406 atomic_set(&hdev->cmd_cnt, 1);
2407 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002408 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002409 }
2410}
2411
2412static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2413{
2414 struct hci_ev_role_change *ev = (void *) skb->data;
2415 struct hci_conn *conn;
2416
2417 BT_DBG("%s status %d", hdev->name, ev->status);
2418
2419 hci_dev_lock(hdev);
2420
2421 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2422 if (conn) {
2423 if (!ev->status) {
2424 if (ev->role)
2425 conn->link_mode &= ~HCI_LM_MASTER;
2426 else
2427 conn->link_mode |= HCI_LM_MASTER;
2428 }
2429
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002430 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002431
2432 hci_role_switch_cfm(conn, ev->status, ev->role);
2433 }
2434
2435 hci_dev_unlock(hdev);
2436}
2437
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2439{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002440 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441 int i;
2442
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002443 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2444 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2445 return;
2446 }
2447
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002448 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2449 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450 BT_DBG("%s bad parameters", hdev->name);
2451 return;
2452 }
2453
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002454 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2455
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002456 for (i = 0; i < ev->num_hndl; i++) {
2457 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458 struct hci_conn *conn;
2459 __u16 handle, count;
2460
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002461 handle = __le16_to_cpu(info->handle);
2462 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002463
2464 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002465 if (!conn)
2466 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002467
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002468 conn->sent -= count;
2469
2470 switch (conn->type) {
2471 case ACL_LINK:
2472 hdev->acl_cnt += count;
2473 if (hdev->acl_cnt > hdev->acl_pkts)
2474 hdev->acl_cnt = hdev->acl_pkts;
2475 break;
2476
2477 case LE_LINK:
2478 if (hdev->le_pkts) {
2479 hdev->le_cnt += count;
2480 if (hdev->le_cnt > hdev->le_pkts)
2481 hdev->le_cnt = hdev->le_pkts;
2482 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002483 hdev->acl_cnt += count;
2484 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485 hdev->acl_cnt = hdev->acl_pkts;
2486 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002487 break;
2488
2489 case SCO_LINK:
2490 hdev->sco_cnt += count;
2491 if (hdev->sco_cnt > hdev->sco_pkts)
2492 hdev->sco_cnt = hdev->sco_pkts;
2493 break;
2494
2495 default:
2496 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2497 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498 }
2499 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002500
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002501 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502}
2503
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002504static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2505 struct sk_buff *skb)
2506{
2507 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2508 int i;
2509
2510 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2511 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2512 return;
2513 }
2514
2515 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2516 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2517 BT_DBG("%s bad parameters", hdev->name);
2518 return;
2519 }
2520
2521 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2522 ev->num_hndl);
2523
2524 for (i = 0; i < ev->num_hndl; i++) {
2525 struct hci_comp_blocks_info *info = &ev->handles[i];
2526 struct hci_conn *conn;
2527 __u16 handle, block_count;
2528
2529 handle = __le16_to_cpu(info->handle);
2530 block_count = __le16_to_cpu(info->blocks);
2531
2532 conn = hci_conn_hash_lookup_handle(hdev, handle);
2533 if (!conn)
2534 continue;
2535
2536 conn->sent -= block_count;
2537
2538 switch (conn->type) {
2539 case ACL_LINK:
2540 hdev->block_cnt += block_count;
2541 if (hdev->block_cnt > hdev->num_blocks)
2542 hdev->block_cnt = hdev->num_blocks;
2543 break;
2544
2545 default:
2546 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2547 break;
2548 }
2549 }
2550
2551 queue_work(hdev->workqueue, &hdev->tx_work);
2552}
2553
Marcel Holtmann04837f62006-07-03 10:02:33 +02002554static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002556 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002557 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558
2559 BT_DBG("%s status %d", hdev->name, ev->status);
2560
2561 hci_dev_lock(hdev);
2562
Marcel Holtmann04837f62006-07-03 10:02:33 +02002563 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2564 if (conn) {
2565 conn->mode = ev->mode;
2566 conn->interval = __le16_to_cpu(ev->interval);
2567
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002568 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002569 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002570 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002571 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002572 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002573 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002574
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002575 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002576 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002577 }
2578
2579 hci_dev_unlock(hdev);
2580}
2581
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2583{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002584 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2585 struct hci_conn *conn;
2586
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002587 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002588
2589 hci_dev_lock(hdev);
2590
2591 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002592 if (!conn)
2593 goto unlock;
2594
2595 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002596 hci_conn_hold(conn);
2597 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2598 hci_conn_put(conn);
2599 }
2600
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002601 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002602 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2603 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002604 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002605 u8 secure;
2606
2607 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2608 secure = 1;
2609 else
2610 secure = 0;
2611
Johan Hedberg744cf192011-11-08 20:40:14 +02002612 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002613 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002614
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002615unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002616 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617}
2618
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2620{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002621 struct hci_ev_link_key_req *ev = (void *) skb->data;
2622 struct hci_cp_link_key_reply cp;
2623 struct hci_conn *conn;
2624 struct link_key *key;
2625
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002626 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002627
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002628 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002629 return;
2630
2631 hci_dev_lock(hdev);
2632
2633 key = hci_find_link_key(hdev, &ev->bdaddr);
2634 if (!key) {
2635 BT_DBG("%s link key not found for %s", hdev->name,
2636 batostr(&ev->bdaddr));
2637 goto not_found;
2638 }
2639
2640 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2641 batostr(&ev->bdaddr));
2642
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002643 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002644 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002645 BT_DBG("%s ignoring debug key", hdev->name);
2646 goto not_found;
2647 }
2648
2649 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002650 if (conn) {
2651 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2652 conn->auth_type != 0xff &&
2653 (conn->auth_type & 0x01)) {
2654 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2655 goto not_found;
2656 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002657
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002658 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2659 conn->pending_sec_level == BT_SECURITY_HIGH) {
2660 BT_DBG("%s ignoring key unauthenticated for high \
2661 security", hdev->name);
2662 goto not_found;
2663 }
2664
2665 conn->key_type = key->type;
2666 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002667 }
2668
2669 bacpy(&cp.bdaddr, &ev->bdaddr);
2670 memcpy(cp.link_key, key->val, 16);
2671
2672 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2673
2674 hci_dev_unlock(hdev);
2675
2676 return;
2677
2678not_found:
2679 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2680 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002681}
2682
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2684{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002685 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2686 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002687 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002688
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002689 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002690
2691 hci_dev_lock(hdev);
2692
2693 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2694 if (conn) {
2695 hci_conn_hold(conn);
2696 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002697 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002698
2699 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2700 conn->key_type = ev->key_type;
2701
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002702 hci_conn_put(conn);
2703 }
2704
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002705 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002706 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002707 ev->key_type, pin_len);
2708
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002709 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710}
2711
Marcel Holtmann04837f62006-07-03 10:02:33 +02002712static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2713{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002714 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002715 struct hci_conn *conn;
2716
2717 BT_DBG("%s status %d", hdev->name, ev->status);
2718
2719 hci_dev_lock(hdev);
2720
2721 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002722 if (conn && !ev->status) {
2723 struct inquiry_entry *ie;
2724
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002725 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2726 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727 ie->data.clock_offset = ev->clock_offset;
2728 ie->timestamp = jiffies;
2729 }
2730 }
2731
2732 hci_dev_unlock(hdev);
2733}
2734
Marcel Holtmanna8746412008-07-14 20:13:46 +02002735static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2736{
2737 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2738 struct hci_conn *conn;
2739
2740 BT_DBG("%s status %d", hdev->name, ev->status);
2741
2742 hci_dev_lock(hdev);
2743
2744 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2745 if (conn && !ev->status)
2746 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2747
2748 hci_dev_unlock(hdev);
2749}
2750
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002751static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2752{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002753 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002754 struct inquiry_entry *ie;
2755
2756 BT_DBG("%s", hdev->name);
2757
2758 hci_dev_lock(hdev);
2759
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002760 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2761 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002762 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2763 ie->timestamp = jiffies;
2764 }
2765
2766 hci_dev_unlock(hdev);
2767}
2768
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002769static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2770{
2771 struct inquiry_data data;
2772 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg31754052012-01-04 13:39:52 +02002773 bool name_known;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002774
2775 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2776
2777 if (!num_rsp)
2778 return;
2779
2780 hci_dev_lock(hdev);
2781
2782 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002783 struct inquiry_info_with_rssi_and_pscan_mode *info;
2784 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002785
Johan Hedberge17acd42011-03-30 23:57:16 +03002786 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002787 bacpy(&data.bdaddr, &info->bdaddr);
2788 data.pscan_rep_mode = info->pscan_rep_mode;
2789 data.pscan_period_mode = info->pscan_period_mode;
2790 data.pscan_mode = info->pscan_mode;
2791 memcpy(data.dev_class, info->dev_class, 3);
2792 data.clock_offset = info->clock_offset;
2793 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002794 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002795
2796 name_known = hci_inquiry_cache_update(hdev, &data,
2797 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002798 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002799 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002800 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002801 }
2802 } else {
2803 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2804
Johan Hedberge17acd42011-03-30 23:57:16 +03002805 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002806 bacpy(&data.bdaddr, &info->bdaddr);
2807 data.pscan_rep_mode = info->pscan_rep_mode;
2808 data.pscan_period_mode = info->pscan_period_mode;
2809 data.pscan_mode = 0x00;
2810 memcpy(data.dev_class, info->dev_class, 3);
2811 data.clock_offset = info->clock_offset;
2812 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002813 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002814 name_known = hci_inquiry_cache_update(hdev, &data,
2815 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002816 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002817 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002818 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002819 }
2820 }
2821
2822 hci_dev_unlock(hdev);
2823}
2824
2825static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2826{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002827 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2828 struct hci_conn *conn;
2829
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002830 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002831
Marcel Holtmann41a96212008-07-14 20:13:48 +02002832 hci_dev_lock(hdev);
2833
2834 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002835 if (!conn)
2836 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002837
Johan Hedbergccd556f2010-11-10 17:11:51 +02002838 if (!ev->status && ev->page == 0x01) {
2839 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002840
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002841 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2842 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002843 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002844
Johan Hedberg58a681e2012-01-16 06:47:28 +02002845 if (ev->features[0] & 0x01)
2846 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002847 }
2848
Johan Hedbergccd556f2010-11-10 17:11:51 +02002849 if (conn->state != BT_CONFIG)
2850 goto unlock;
2851
Johan Hedberg127178d2010-11-18 22:22:29 +02002852 if (!ev->status) {
2853 struct hci_cp_remote_name_req cp;
2854 memset(&cp, 0, sizeof(cp));
2855 bacpy(&cp.bdaddr, &conn->dst);
2856 cp.pscan_rep_mode = 0x02;
2857 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002858 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2859 mgmt_device_connected(hdev, &conn->dst, conn->type,
2860 conn->dst_type, NULL, 0,
2861 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002862
Johan Hedberg127178d2010-11-18 22:22:29 +02002863 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002864 conn->state = BT_CONNECTED;
2865 hci_proto_connect_cfm(conn, ev->status);
2866 hci_conn_put(conn);
2867 }
2868
2869unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002870 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002871}
2872
2873static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2874{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002875 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2876 struct hci_conn *conn;
2877
2878 BT_DBG("%s status %d", hdev->name, ev->status);
2879
2880 hci_dev_lock(hdev);
2881
2882 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002883 if (!conn) {
2884 if (ev->link_type == ESCO_LINK)
2885 goto unlock;
2886
2887 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2888 if (!conn)
2889 goto unlock;
2890
2891 conn->type = SCO_LINK;
2892 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002893
Marcel Holtmann732547f2009-04-19 19:14:14 +02002894 switch (ev->status) {
2895 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002896 conn->handle = __le16_to_cpu(ev->handle);
2897 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002898
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002899 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002900 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002901 break;
2902
Stephen Coe705e5712010-02-16 11:29:44 -05002903 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002904 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002905 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002906 case 0x1f: /* Unspecified error */
2907 if (conn->out && conn->attempt < 2) {
2908 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2909 (hdev->esco_type & EDR_ESCO_MASK);
2910 hci_setup_sync(conn, conn->link->handle);
2911 goto unlock;
2912 }
2913 /* fall through */
2914
2915 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002916 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002917 break;
2918 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002919
2920 hci_proto_connect_cfm(conn, ev->status);
2921 if (ev->status)
2922 hci_conn_del(conn);
2923
2924unlock:
2925 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002926}
2927
2928static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2929{
2930 BT_DBG("%s", hdev->name);
2931}
2932
Marcel Holtmann04837f62006-07-03 10:02:33 +02002933static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2934{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002935 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002936
2937 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002938}
2939
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002940static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2941{
2942 struct inquiry_data data;
2943 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2944 int num_rsp = *((__u8 *) skb->data);
2945
2946 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2947
2948 if (!num_rsp)
2949 return;
2950
2951 hci_dev_lock(hdev);
2952
Johan Hedberge17acd42011-03-30 23:57:16 +03002953 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg561aafb2012-01-04 13:31:59 +02002954 bool name_known;
2955
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002956 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002957 data.pscan_rep_mode = info->pscan_rep_mode;
2958 data.pscan_period_mode = info->pscan_period_mode;
2959 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002960 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002961 data.clock_offset = info->clock_offset;
2962 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002963 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002964
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002965 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002966 name_known = eir_has_data_type(info->data,
2967 sizeof(info->data),
2968 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002969 else
2970 name_known = true;
2971
Johan Hedberg31754052012-01-04 13:39:52 +02002972 name_known = hci_inquiry_cache_update(hdev, &data, name_known);
Johan Hedberg48264f02011-11-09 13:58:58 +02002973 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002974 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002975 !name_known, info->data,
2976 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002977 }
2978
2979 hci_dev_unlock(hdev);
2980}
2981
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002982static inline u8 hci_get_auth_req(struct hci_conn *conn)
2983{
2984 /* If remote requests dedicated bonding follow that lead */
2985 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2986 /* If both remote and local IO capabilities allow MITM
2987 * protection then require it, otherwise don't */
2988 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2989 return 0x02;
2990 else
2991 return 0x03;
2992 }
2993
2994 /* If remote requests no-bonding follow that lead */
2995 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002996 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002997
2998 return conn->auth_type;
2999}
3000
Marcel Holtmann04936842008-07-14 20:13:48 +02003001static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3002{
3003 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3004 struct hci_conn *conn;
3005
3006 BT_DBG("%s", hdev->name);
3007
3008 hci_dev_lock(hdev);
3009
3010 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003011 if (!conn)
3012 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003013
Johan Hedberg03b555e2011-01-04 15:40:05 +02003014 hci_conn_hold(conn);
3015
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003016 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003017 goto unlock;
3018
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003019 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003020 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003021 struct hci_cp_io_capability_reply cp;
3022
3023 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303024 /* Change the IO capability from KeyboardDisplay
3025 * to DisplayYesNo as it is not supported by BT spec. */
3026 cp.capability = (conn->io_capability == 0x04) ?
3027 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003028 conn->auth_type = hci_get_auth_req(conn);
3029 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003030
Johan Hedberg58a681e2012-01-16 06:47:28 +02003031 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003032 hci_find_remote_oob_data(hdev, &conn->dst))
3033 cp.oob_data = 0x01;
3034 else
3035 cp.oob_data = 0x00;
3036
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003037 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3038 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003039 } else {
3040 struct hci_cp_io_capability_neg_reply cp;
3041
3042 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003043 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003044
3045 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3046 sizeof(cp), &cp);
3047 }
3048
3049unlock:
3050 hci_dev_unlock(hdev);
3051}
3052
3053static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3054{
3055 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3056 struct hci_conn *conn;
3057
3058 BT_DBG("%s", hdev->name);
3059
3060 hci_dev_lock(hdev);
3061
3062 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3063 if (!conn)
3064 goto unlock;
3065
Johan Hedberg03b555e2011-01-04 15:40:05 +02003066 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003067 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003068 if (ev->oob_data)
3069 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003070
3071unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003072 hci_dev_unlock(hdev);
3073}
3074
Johan Hedberga5c29682011-02-19 12:05:57 -03003075static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3076 struct sk_buff *skb)
3077{
3078 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003079 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003080 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003081
3082 BT_DBG("%s", hdev->name);
3083
3084 hci_dev_lock(hdev);
3085
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003086 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003087 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003088
Johan Hedberg7a828902011-04-28 11:28:53 -07003089 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3090 if (!conn)
3091 goto unlock;
3092
3093 loc_mitm = (conn->auth_type & 0x01);
3094 rem_mitm = (conn->remote_auth & 0x01);
3095
3096 /* If we require MITM but the remote device can't provide that
3097 * (it has NoInputNoOutput) then reject the confirmation
3098 * request. The only exception is when we're dedicated bonding
3099 * initiators (connect_cfm_cb set) since then we always have the MITM
3100 * bit set. */
3101 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3102 BT_DBG("Rejecting request: remote device can't provide MITM");
3103 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3104 sizeof(ev->bdaddr), &ev->bdaddr);
3105 goto unlock;
3106 }
3107
3108 /* If no side requires MITM protection; auto-accept */
3109 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3110 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003111
3112 /* If we're not the initiators request authorization to
3113 * proceed from user space (mgmt_user_confirm with
3114 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003115 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003116 BT_DBG("Confirming auto-accept as acceptor");
3117 confirm_hint = 1;
3118 goto confirm;
3119 }
3120
Johan Hedberg9f616562011-04-28 11:28:54 -07003121 BT_DBG("Auto-accept of user confirmation with %ums delay",
3122 hdev->auto_accept_delay);
3123
3124 if (hdev->auto_accept_delay > 0) {
3125 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3126 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3127 goto unlock;
3128 }
3129
Johan Hedberg7a828902011-04-28 11:28:53 -07003130 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3131 sizeof(ev->bdaddr), &ev->bdaddr);
3132 goto unlock;
3133 }
3134
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003135confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003136 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003137 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003138
3139unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003140 hci_dev_unlock(hdev);
3141}
3142
Brian Gix1143d452011-11-23 08:28:34 -08003143static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3144 struct sk_buff *skb)
3145{
3146 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3147
3148 BT_DBG("%s", hdev->name);
3149
3150 hci_dev_lock(hdev);
3151
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003152 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003153 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003154
3155 hci_dev_unlock(hdev);
3156}
3157
Marcel Holtmann04936842008-07-14 20:13:48 +02003158static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3159{
3160 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3161 struct hci_conn *conn;
3162
3163 BT_DBG("%s", hdev->name);
3164
3165 hci_dev_lock(hdev);
3166
3167 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003168 if (!conn)
3169 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003170
Johan Hedberg2a611692011-02-19 12:06:00 -03003171 /* To avoid duplicate auth_failed events to user space we check
3172 * the HCI_CONN_AUTH_PEND flag which will be set if we
3173 * initiated the authentication. A traditional auth_complete
3174 * event gets always produced as initiator and is also mapped to
3175 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003176 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003177 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3178 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003179
3180 hci_conn_put(conn);
3181
3182unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003183 hci_dev_unlock(hdev);
3184}
3185
Marcel Holtmann41a96212008-07-14 20:13:48 +02003186static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3187{
3188 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3189 struct inquiry_entry *ie;
3190
3191 BT_DBG("%s", hdev->name);
3192
3193 hci_dev_lock(hdev);
3194
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003195 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3196 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003197 ie->data.ssp_mode = (ev->features[0] & 0x01);
3198
3199 hci_dev_unlock(hdev);
3200}
3201
Szymon Janc2763eda2011-03-22 13:12:22 +01003202static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3203 struct sk_buff *skb)
3204{
3205 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3206 struct oob_data *data;
3207
3208 BT_DBG("%s", hdev->name);
3209
3210 hci_dev_lock(hdev);
3211
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003212 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003213 goto unlock;
3214
Szymon Janc2763eda2011-03-22 13:12:22 +01003215 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3216 if (data) {
3217 struct hci_cp_remote_oob_data_reply cp;
3218
3219 bacpy(&cp.bdaddr, &ev->bdaddr);
3220 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3221 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3222
3223 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3224 &cp);
3225 } else {
3226 struct hci_cp_remote_oob_data_neg_reply cp;
3227
3228 bacpy(&cp.bdaddr, &ev->bdaddr);
3229 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3230 &cp);
3231 }
3232
Szymon Jance1ba1f12011-04-06 13:01:59 +02003233unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003234 hci_dev_unlock(hdev);
3235}
3236
Ville Tervofcd89c02011-02-10 22:38:47 -03003237static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3238{
3239 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3240 struct hci_conn *conn;
3241
3242 BT_DBG("%s status %d", hdev->name, ev->status);
3243
3244 hci_dev_lock(hdev);
3245
3246 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003247 if (!conn) {
3248 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3249 if (!conn) {
3250 BT_ERR("No memory for new connection");
3251 hci_dev_unlock(hdev);
3252 return;
3253 }
Andre Guedes29b79882011-05-31 14:20:54 -03003254
3255 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003256 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003257
3258 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003259 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3260 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003261 hci_proto_connect_cfm(conn, ev->status);
3262 conn->state = BT_CLOSED;
3263 hci_conn_del(conn);
3264 goto unlock;
3265 }
3266
Johan Hedbergb644ba32012-01-17 21:48:47 +02003267 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3268 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3269 conn->dst_type, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003270
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003271 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003272 conn->handle = __le16_to_cpu(ev->handle);
3273 conn->state = BT_CONNECTED;
3274
3275 hci_conn_hold_device(conn);
3276 hci_conn_add_sysfs(conn);
3277
3278 hci_proto_connect_cfm(conn, ev->status);
3279
3280unlock:
3281 hci_dev_unlock(hdev);
3282}
3283
Andre Guedes9aa04c92011-05-26 16:23:51 -03003284static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3285 struct sk_buff *skb)
3286{
Andre Guedese95beb42011-09-26 20:48:35 -03003287 u8 num_reports = skb->data[0];
3288 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003289 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003290
3291 hci_dev_lock(hdev);
3292
Andre Guedese95beb42011-09-26 20:48:35 -03003293 while (num_reports--) {
3294 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003295
Andre Guedes9aa04c92011-05-26 16:23:51 -03003296 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003297
Andre Guedes3c9e9192012-01-10 18:20:50 -03003298 rssi = ev->data[ev->length];
3299 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3300 NULL, rssi, 0, ev->data, ev->length);
3301
Andre Guedese95beb42011-09-26 20:48:35 -03003302 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003303 }
3304
3305 hci_dev_unlock(hdev);
3306}
3307
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003308static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3309 struct sk_buff *skb)
3310{
3311 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3312 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003313 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003314 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003315 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003316
3317 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3318
3319 hci_dev_lock(hdev);
3320
3321 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003322 if (conn == NULL)
3323 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003324
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003325 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3326 if (ltk == NULL)
3327 goto not_found;
3328
3329 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003330 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003331
3332 if (ltk->authenticated)
3333 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003334
3335 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3336
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003337 if (ltk->type & HCI_SMP_STK) {
3338 list_del(&ltk->list);
3339 kfree(ltk);
3340 }
3341
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003342 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003343
3344 return;
3345
3346not_found:
3347 neg.handle = ev->handle;
3348 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3349 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003350}
3351
Ville Tervofcd89c02011-02-10 22:38:47 -03003352static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3353{
3354 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3355
3356 skb_pull(skb, sizeof(*le_ev));
3357
3358 switch (le_ev->subevent) {
3359 case HCI_EV_LE_CONN_COMPLETE:
3360 hci_le_conn_complete_evt(hdev, skb);
3361 break;
3362
Andre Guedes9aa04c92011-05-26 16:23:51 -03003363 case HCI_EV_LE_ADVERTISING_REPORT:
3364 hci_le_adv_report_evt(hdev, skb);
3365 break;
3366
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003367 case HCI_EV_LE_LTK_REQ:
3368 hci_le_ltk_request_evt(hdev, skb);
3369 break;
3370
Ville Tervofcd89c02011-02-10 22:38:47 -03003371 default:
3372 break;
3373 }
3374}
3375
Linus Torvalds1da177e2005-04-16 15:20:36 -07003376void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3377{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003378 struct hci_event_hdr *hdr = (void *) skb->data;
3379 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003380
3381 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3382
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003383 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003384 case HCI_EV_INQUIRY_COMPLETE:
3385 hci_inquiry_complete_evt(hdev, skb);
3386 break;
3387
3388 case HCI_EV_INQUIRY_RESULT:
3389 hci_inquiry_result_evt(hdev, skb);
3390 break;
3391
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003392 case HCI_EV_CONN_COMPLETE:
3393 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003394 break;
3395
Linus Torvalds1da177e2005-04-16 15:20:36 -07003396 case HCI_EV_CONN_REQUEST:
3397 hci_conn_request_evt(hdev, skb);
3398 break;
3399
Linus Torvalds1da177e2005-04-16 15:20:36 -07003400 case HCI_EV_DISCONN_COMPLETE:
3401 hci_disconn_complete_evt(hdev, skb);
3402 break;
3403
Linus Torvalds1da177e2005-04-16 15:20:36 -07003404 case HCI_EV_AUTH_COMPLETE:
3405 hci_auth_complete_evt(hdev, skb);
3406 break;
3407
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003408 case HCI_EV_REMOTE_NAME:
3409 hci_remote_name_evt(hdev, skb);
3410 break;
3411
Linus Torvalds1da177e2005-04-16 15:20:36 -07003412 case HCI_EV_ENCRYPT_CHANGE:
3413 hci_encrypt_change_evt(hdev, skb);
3414 break;
3415
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003416 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3417 hci_change_link_key_complete_evt(hdev, skb);
3418 break;
3419
3420 case HCI_EV_REMOTE_FEATURES:
3421 hci_remote_features_evt(hdev, skb);
3422 break;
3423
3424 case HCI_EV_REMOTE_VERSION:
3425 hci_remote_version_evt(hdev, skb);
3426 break;
3427
3428 case HCI_EV_QOS_SETUP_COMPLETE:
3429 hci_qos_setup_complete_evt(hdev, skb);
3430 break;
3431
3432 case HCI_EV_CMD_COMPLETE:
3433 hci_cmd_complete_evt(hdev, skb);
3434 break;
3435
3436 case HCI_EV_CMD_STATUS:
3437 hci_cmd_status_evt(hdev, skb);
3438 break;
3439
3440 case HCI_EV_ROLE_CHANGE:
3441 hci_role_change_evt(hdev, skb);
3442 break;
3443
3444 case HCI_EV_NUM_COMP_PKTS:
3445 hci_num_comp_pkts_evt(hdev, skb);
3446 break;
3447
3448 case HCI_EV_MODE_CHANGE:
3449 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003450 break;
3451
3452 case HCI_EV_PIN_CODE_REQ:
3453 hci_pin_code_request_evt(hdev, skb);
3454 break;
3455
3456 case HCI_EV_LINK_KEY_REQ:
3457 hci_link_key_request_evt(hdev, skb);
3458 break;
3459
3460 case HCI_EV_LINK_KEY_NOTIFY:
3461 hci_link_key_notify_evt(hdev, skb);
3462 break;
3463
3464 case HCI_EV_CLOCK_OFFSET:
3465 hci_clock_offset_evt(hdev, skb);
3466 break;
3467
Marcel Holtmanna8746412008-07-14 20:13:46 +02003468 case HCI_EV_PKT_TYPE_CHANGE:
3469 hci_pkt_type_change_evt(hdev, skb);
3470 break;
3471
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003472 case HCI_EV_PSCAN_REP_MODE:
3473 hci_pscan_rep_mode_evt(hdev, skb);
3474 break;
3475
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003476 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3477 hci_inquiry_result_with_rssi_evt(hdev, skb);
3478 break;
3479
3480 case HCI_EV_REMOTE_EXT_FEATURES:
3481 hci_remote_ext_features_evt(hdev, skb);
3482 break;
3483
3484 case HCI_EV_SYNC_CONN_COMPLETE:
3485 hci_sync_conn_complete_evt(hdev, skb);
3486 break;
3487
3488 case HCI_EV_SYNC_CONN_CHANGED:
3489 hci_sync_conn_changed_evt(hdev, skb);
3490 break;
3491
Marcel Holtmann04837f62006-07-03 10:02:33 +02003492 case HCI_EV_SNIFF_SUBRATE:
3493 hci_sniff_subrate_evt(hdev, skb);
3494 break;
3495
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003496 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3497 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003498 break;
3499
Marcel Holtmann04936842008-07-14 20:13:48 +02003500 case HCI_EV_IO_CAPA_REQUEST:
3501 hci_io_capa_request_evt(hdev, skb);
3502 break;
3503
Johan Hedberg03b555e2011-01-04 15:40:05 +02003504 case HCI_EV_IO_CAPA_REPLY:
3505 hci_io_capa_reply_evt(hdev, skb);
3506 break;
3507
Johan Hedberga5c29682011-02-19 12:05:57 -03003508 case HCI_EV_USER_CONFIRM_REQUEST:
3509 hci_user_confirm_request_evt(hdev, skb);
3510 break;
3511
Brian Gix1143d452011-11-23 08:28:34 -08003512 case HCI_EV_USER_PASSKEY_REQUEST:
3513 hci_user_passkey_request_evt(hdev, skb);
3514 break;
3515
Marcel Holtmann04936842008-07-14 20:13:48 +02003516 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3517 hci_simple_pair_complete_evt(hdev, skb);
3518 break;
3519
Marcel Holtmann41a96212008-07-14 20:13:48 +02003520 case HCI_EV_REMOTE_HOST_FEATURES:
3521 hci_remote_host_features_evt(hdev, skb);
3522 break;
3523
Ville Tervofcd89c02011-02-10 22:38:47 -03003524 case HCI_EV_LE_META:
3525 hci_le_meta_evt(hdev, skb);
3526 break;
3527
Szymon Janc2763eda2011-03-22 13:12:22 +01003528 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3529 hci_remote_oob_data_request_evt(hdev, skb);
3530 break;
3531
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003532 case HCI_EV_NUM_COMP_BLOCKS:
3533 hci_num_comp_blocks_evt(hdev, skb);
3534 break;
3535
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003536 default:
3537 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003538 break;
3539 }
3540
3541 kfree_skb(skb);
3542 hdev->stat.evt_rx++;
3543}