blob: 5d0f92a948c24882137f0d77a3eb92497c5cc3bc [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 Hedberg7005ff1782012-01-18 16:14:43 +0200195 /* Reset all flags, except persistent ones */
Hemant Gupta95947a32012-01-23 15:36:11 +0530196 hdev->dev_flags &= BIT(HCI_MGMT) | BIT(HCI_SETUP) | BIT(HCI_AUTO_OFF) |
197 BIT(HCI_LINK_KEYS) | BIT(HCI_DEBUG_KEYS);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200198}
199
200static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
201{
202 __u8 status = *((__u8 *) skb->data);
203 void *sent;
204
205 BT_DBG("%s status 0x%x", hdev->name, status);
206
207 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
208 if (!sent)
209 return;
210
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200211 hci_dev_lock(hdev);
212
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200213 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200214 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200215
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200216 if (status == 0)
217 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200218
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200219 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200220}
221
222static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
223{
224 struct hci_rp_read_local_name *rp = (void *) skb->data;
225
226 BT_DBG("%s status 0x%x", hdev->name, rp->status);
227
228 if (rp->status)
229 return;
230
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200231 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200232}
233
234static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
235{
236 __u8 status = *((__u8 *) skb->data);
237 void *sent;
238
239 BT_DBG("%s status 0x%x", hdev->name, status);
240
241 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
242 if (!sent)
243 return;
244
245 if (!status) {
246 __u8 param = *((__u8 *) sent);
247
248 if (param == AUTH_ENABLED)
249 set_bit(HCI_AUTH, &hdev->flags);
250 else
251 clear_bit(HCI_AUTH, &hdev->flags);
252 }
253
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200254 if (test_bit(HCI_MGMT, &hdev->dev_flags))
255 mgmt_auth_enable_complete(hdev, status);
256
Johan Hedberg23bb5762010-12-21 23:01:27 +0200257 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200258}
259
260static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
261{
262 __u8 status = *((__u8 *) skb->data);
263 void *sent;
264
265 BT_DBG("%s status 0x%x", hdev->name, status);
266
267 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
268 if (!sent)
269 return;
270
271 if (!status) {
272 __u8 param = *((__u8 *) sent);
273
274 if (param)
275 set_bit(HCI_ENCRYPT, &hdev->flags);
276 else
277 clear_bit(HCI_ENCRYPT, &hdev->flags);
278 }
279
Johan Hedberg23bb5762010-12-21 23:01:27 +0200280 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200281}
282
283static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
284{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200285 __u8 param, status = *((__u8 *) skb->data);
286 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200287 void *sent;
288
289 BT_DBG("%s status 0x%x", hdev->name, status);
290
291 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
292 if (!sent)
293 return;
294
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200295 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200296
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200297 hci_dev_lock(hdev);
298
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200299 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200300 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200301 hdev->discov_timeout = 0;
302 goto done;
303 }
304
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200305 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
306 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200307
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200308 if (param & SCAN_INQUIRY) {
309 set_bit(HCI_ISCAN, &hdev->flags);
310 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200311 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200312 if (hdev->discov_timeout > 0) {
313 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
314 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
315 to);
316 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200317 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200318 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200319
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200320 if (param & SCAN_PAGE) {
321 set_bit(HCI_PSCAN, &hdev->flags);
322 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200323 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200324 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200325 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200326
327done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200328 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200329 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200330}
331
332static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
333{
334 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
335
336 BT_DBG("%s status 0x%x", hdev->name, rp->status);
337
338 if (rp->status)
339 return;
340
341 memcpy(hdev->dev_class, rp->dev_class, 3);
342
343 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
344 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
345}
346
347static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
348{
349 __u8 status = *((__u8 *) skb->data);
350 void *sent;
351
352 BT_DBG("%s status 0x%x", hdev->name, status);
353
Marcel Holtmannf383f272008-07-14 20:13:47 +0200354 if (status)
355 return;
356
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200357 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
358 if (!sent)
359 return;
360
Marcel Holtmannf383f272008-07-14 20:13:47 +0200361 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200362}
363
364static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
365{
366 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200368
369 BT_DBG("%s status 0x%x", hdev->name, rp->status);
370
371 if (rp->status)
372 return;
373
374 setting = __le16_to_cpu(rp->voice_setting);
375
Marcel Holtmannf383f272008-07-14 20:13:47 +0200376 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200377 return;
378
379 hdev->voice_setting = setting;
380
381 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
382
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200383 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200385}
386
387static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
388{
389 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200390 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 void *sent;
392
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200393 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394
Marcel Holtmannf383f272008-07-14 20:13:47 +0200395 if (status)
396 return;
397
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200398 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
399 if (!sent)
400 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401
Marcel Holtmannf383f272008-07-14 20:13:47 +0200402 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403
Marcel Holtmannf383f272008-07-14 20:13:47 +0200404 if (hdev->voice_setting == setting)
405 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
Marcel Holtmannf383f272008-07-14 20:13:47 +0200407 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Marcel Holtmannf383f272008-07-14 20:13:47 +0200409 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
410
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200411 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200412 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413}
414
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200415static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200417 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200419 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
Johan Hedberg23bb5762010-12-21 23:01:27 +0200421 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422}
423
Marcel Holtmann333140b2008-07-14 20:13:48 +0200424static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
425{
426 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
427
428 BT_DBG("%s status 0x%x", hdev->name, rp->status);
429
430 if (rp->status)
431 return;
432
Johan Hedberg84bde9d2012-01-25 14:21:06 +0200433 if (rp->mode)
434 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
435 else
436 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200437}
438
439static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
440{
441 __u8 status = *((__u8 *) skb->data);
442 void *sent;
443
444 BT_DBG("%s status 0x%x", hdev->name, status);
445
446 if (status)
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200447 goto done;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200448
449 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
450 if (!sent)
451 return;
452
Johan Hedberg84bde9d2012-01-25 14:21:06 +0200453 if (*((u8 *) sent))
454 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
455 else
456 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200457
458done:
459 if (test_bit(HCI_MGMT, &hdev->dev_flags))
460 mgmt_ssp_enable_complete(hdev, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200461}
462
Johan Hedbergd5859e22011-01-25 01:19:58 +0200463static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
464{
465 if (hdev->features[6] & LMP_EXT_INQ)
466 return 2;
467
468 if (hdev->features[3] & LMP_RSSI_INQ)
469 return 1;
470
471 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
472 hdev->lmp_subver == 0x0757)
473 return 1;
474
475 if (hdev->manufacturer == 15) {
476 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
477 return 1;
478 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
479 return 1;
480 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
481 return 1;
482 }
483
484 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
485 hdev->lmp_subver == 0x1805)
486 return 1;
487
488 return 0;
489}
490
491static void hci_setup_inquiry_mode(struct hci_dev *hdev)
492{
493 u8 mode;
494
495 mode = hci_get_inquiry_mode(hdev);
496
497 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
498}
499
500static void hci_setup_event_mask(struct hci_dev *hdev)
501{
502 /* The second byte is 0xff instead of 0x9f (two reserved bits
503 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
504 * command otherwise */
505 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
506
Ville Tervo6de6c182011-05-27 11:16:21 +0300507 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
508 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200509 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300510 return;
511
512 events[4] |= 0x01; /* Flow Specification Complete */
513 events[4] |= 0x02; /* Inquiry Result with RSSI */
514 events[4] |= 0x04; /* Read Remote Extended Features Complete */
515 events[5] |= 0x08; /* Synchronous Connection Complete */
516 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200517
518 if (hdev->features[3] & LMP_RSSI_INQ)
519 events[4] |= 0x04; /* Inquiry Result with RSSI */
520
521 if (hdev->features[5] & LMP_SNIFF_SUBR)
522 events[5] |= 0x20; /* Sniff Subrating */
523
524 if (hdev->features[5] & LMP_PAUSE_ENC)
525 events[5] |= 0x80; /* Encryption Key Refresh Complete */
526
527 if (hdev->features[6] & LMP_EXT_INQ)
528 events[5] |= 0x40; /* Extended Inquiry Result */
529
530 if (hdev->features[6] & LMP_NO_FLUSH)
531 events[7] |= 0x01; /* Enhanced Flush Complete */
532
533 if (hdev->features[7] & LMP_LSTO)
534 events[6] |= 0x80; /* Link Supervision Timeout Changed */
535
536 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
537 events[6] |= 0x01; /* IO Capability Request */
538 events[6] |= 0x02; /* IO Capability Response */
539 events[6] |= 0x04; /* User Confirmation Request */
540 events[6] |= 0x08; /* User Passkey Request */
541 events[6] |= 0x10; /* Remote OOB Data Request */
542 events[6] |= 0x20; /* Simple Pairing Complete */
543 events[7] |= 0x04; /* User Passkey Notification */
544 events[7] |= 0x08; /* Keypress Notification */
545 events[7] |= 0x10; /* Remote Host Supported
546 * Features Notification */
547 }
548
549 if (hdev->features[4] & LMP_LE)
550 events[7] |= 0x20; /* LE Meta-Event */
551
552 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
553}
554
Andre Guedese6100a22011-06-30 19:20:54 -0300555static void hci_set_le_support(struct hci_dev *hdev)
556{
557 struct hci_cp_write_le_host_supported cp;
558
559 memset(&cp, 0, sizeof(cp));
560
561 if (enable_le) {
562 cp.le = 1;
563 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
564 }
565
566 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
567}
568
Johan Hedbergd5859e22011-01-25 01:19:58 +0200569static void hci_setup(struct hci_dev *hdev)
570{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200571 if (hdev->dev_type != HCI_BREDR)
572 return;
573
Johan Hedbergd5859e22011-01-25 01:19:58 +0200574 hci_setup_event_mask(hdev);
575
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200576 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200577 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
578
579 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
580 u8 mode = 0x01;
581 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
582 }
583
584 if (hdev->features[3] & LMP_RSSI_INQ)
585 hci_setup_inquiry_mode(hdev);
586
587 if (hdev->features[7] & LMP_INQ_TX_PWR)
588 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300589
590 if (hdev->features[7] & LMP_EXTFEATURES) {
591 struct hci_cp_read_local_ext_features cp;
592
593 cp.page = 0x01;
594 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
595 sizeof(cp), &cp);
596 }
Andre Guedese6100a22011-06-30 19:20:54 -0300597
598 if (hdev->features[4] & LMP_LE)
599 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200600}
601
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200602static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
603{
604 struct hci_rp_read_local_version *rp = (void *) skb->data;
605
606 BT_DBG("%s status 0x%x", hdev->name, rp->status);
607
608 if (rp->status)
609 return;
610
611 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200612 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200613 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200614 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200615 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200616
617 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
618 hdev->manufacturer,
619 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200620
621 if (test_bit(HCI_INIT, &hdev->flags))
622 hci_setup(hdev);
623}
624
625static void hci_setup_link_policy(struct hci_dev *hdev)
626{
627 u16 link_policy = 0;
628
629 if (hdev->features[0] & LMP_RSWITCH)
630 link_policy |= HCI_LP_RSWITCH;
631 if (hdev->features[0] & LMP_HOLD)
632 link_policy |= HCI_LP_HOLD;
633 if (hdev->features[0] & LMP_SNIFF)
634 link_policy |= HCI_LP_SNIFF;
635 if (hdev->features[1] & LMP_PARK)
636 link_policy |= HCI_LP_PARK;
637
638 link_policy = cpu_to_le16(link_policy);
639 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
640 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200641}
642
643static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
644{
645 struct hci_rp_read_local_commands *rp = (void *) skb->data;
646
647 BT_DBG("%s status 0x%x", hdev->name, rp->status);
648
649 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200650 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200651
652 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200653
654 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
655 hci_setup_link_policy(hdev);
656
657done:
658 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200659}
660
661static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
662{
663 struct hci_rp_read_local_features *rp = (void *) skb->data;
664
665 BT_DBG("%s status 0x%x", hdev->name, rp->status);
666
667 if (rp->status)
668 return;
669
670 memcpy(hdev->features, rp->features, 8);
671
672 /* Adjust default settings according to features
673 * supported by device. */
674
675 if (hdev->features[0] & LMP_3SLOT)
676 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
677
678 if (hdev->features[0] & LMP_5SLOT)
679 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
680
681 if (hdev->features[1] & LMP_HV2) {
682 hdev->pkt_type |= (HCI_HV2);
683 hdev->esco_type |= (ESCO_HV2);
684 }
685
686 if (hdev->features[1] & LMP_HV3) {
687 hdev->pkt_type |= (HCI_HV3);
688 hdev->esco_type |= (ESCO_HV3);
689 }
690
691 if (hdev->features[3] & LMP_ESCO)
692 hdev->esco_type |= (ESCO_EV3);
693
694 if (hdev->features[4] & LMP_EV4)
695 hdev->esco_type |= (ESCO_EV4);
696
697 if (hdev->features[4] & LMP_EV5)
698 hdev->esco_type |= (ESCO_EV5);
699
Marcel Holtmannefc76882009-02-06 09:13:37 +0100700 if (hdev->features[5] & LMP_EDR_ESCO_2M)
701 hdev->esco_type |= (ESCO_2EV3);
702
703 if (hdev->features[5] & LMP_EDR_ESCO_3M)
704 hdev->esco_type |= (ESCO_3EV3);
705
706 if (hdev->features[5] & LMP_EDR_3S_ESCO)
707 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
708
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200709 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
710 hdev->features[0], hdev->features[1],
711 hdev->features[2], hdev->features[3],
712 hdev->features[4], hdev->features[5],
713 hdev->features[6], hdev->features[7]);
714}
715
Andre Guedes971e3a42011-06-30 19:20:52 -0300716static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
717 struct sk_buff *skb)
718{
719 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
720
721 BT_DBG("%s status 0x%x", hdev->name, rp->status);
722
723 if (rp->status)
724 return;
725
Andre Guedesb5b32b62011-12-30 10:34:04 -0300726 switch (rp->page) {
727 case 0:
728 memcpy(hdev->features, rp->features, 8);
729 break;
730 case 1:
731 memcpy(hdev->host_features, rp->features, 8);
732 break;
733 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300734
735 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
736}
737
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200738static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
739 struct sk_buff *skb)
740{
741 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
742
743 BT_DBG("%s status 0x%x", hdev->name, rp->status);
744
745 if (rp->status)
746 return;
747
748 hdev->flow_ctl_mode = rp->mode;
749
750 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
751}
752
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200753static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
754{
755 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
756
757 BT_DBG("%s status 0x%x", hdev->name, rp->status);
758
759 if (rp->status)
760 return;
761
762 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
763 hdev->sco_mtu = rp->sco_mtu;
764 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
765 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
766
767 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
768 hdev->sco_mtu = 64;
769 hdev->sco_pkts = 8;
770 }
771
772 hdev->acl_cnt = hdev->acl_pkts;
773 hdev->sco_cnt = hdev->sco_pkts;
774
775 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
776 hdev->acl_mtu, hdev->acl_pkts,
777 hdev->sco_mtu, hdev->sco_pkts);
778}
779
780static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
781{
782 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
783
784 BT_DBG("%s status 0x%x", hdev->name, rp->status);
785
786 if (!rp->status)
787 bacpy(&hdev->bdaddr, &rp->bdaddr);
788
Johan Hedberg23bb5762010-12-21 23:01:27 +0200789 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
790}
791
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200792static void hci_cc_read_data_block_size(struct hci_dev *hdev,
793 struct sk_buff *skb)
794{
795 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
796
797 BT_DBG("%s status 0x%x", hdev->name, rp->status);
798
799 if (rp->status)
800 return;
801
802 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
803 hdev->block_len = __le16_to_cpu(rp->block_len);
804 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
805
806 hdev->block_cnt = hdev->num_blocks;
807
808 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
809 hdev->block_cnt, hdev->block_len);
810
811 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
812}
813
Johan Hedberg23bb5762010-12-21 23:01:27 +0200814static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
815{
816 __u8 status = *((__u8 *) skb->data);
817
818 BT_DBG("%s status 0x%x", hdev->name, status);
819
820 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200821}
822
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300823static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
824 struct sk_buff *skb)
825{
826 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
827
828 BT_DBG("%s status 0x%x", hdev->name, rp->status);
829
830 if (rp->status)
831 return;
832
833 hdev->amp_status = rp->amp_status;
834 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
835 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
836 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
837 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
838 hdev->amp_type = rp->amp_type;
839 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
840 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
841 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
842 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
843
844 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
845}
846
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200847static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
848 struct sk_buff *skb)
849{
850 __u8 status = *((__u8 *) skb->data);
851
852 BT_DBG("%s status 0x%x", hdev->name, status);
853
854 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
855}
856
Johan Hedbergd5859e22011-01-25 01:19:58 +0200857static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
858{
859 __u8 status = *((__u8 *) skb->data);
860
861 BT_DBG("%s status 0x%x", hdev->name, status);
862
863 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
864}
865
866static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
867 struct sk_buff *skb)
868{
869 __u8 status = *((__u8 *) skb->data);
870
871 BT_DBG("%s status 0x%x", hdev->name, status);
872
873 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
874}
875
876static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
877 struct sk_buff *skb)
878{
879 __u8 status = *((__u8 *) skb->data);
880
881 BT_DBG("%s status 0x%x", hdev->name, status);
882
883 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
884}
885
886static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
887{
888 __u8 status = *((__u8 *) skb->data);
889
890 BT_DBG("%s status 0x%x", hdev->name, status);
891
892 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
893}
894
Johan Hedberg980e1a52011-01-22 06:10:07 +0200895static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
896{
897 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
898 struct hci_cp_pin_code_reply *cp;
899 struct hci_conn *conn;
900
901 BT_DBG("%s status 0x%x", hdev->name, rp->status);
902
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200903 hci_dev_lock(hdev);
904
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200905 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200906 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200907
908 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200909 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200910
911 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
912 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200913 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200914
915 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
916 if (conn)
917 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200918
919unlock:
920 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200921}
922
923static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
924{
925 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
926
927 BT_DBG("%s status 0x%x", hdev->name, rp->status);
928
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200929 hci_dev_lock(hdev);
930
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200931 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200932 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200933 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200934
935 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200936}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200937
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300938static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
939 struct sk_buff *skb)
940{
941 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
942
943 BT_DBG("%s status 0x%x", hdev->name, rp->status);
944
945 if (rp->status)
946 return;
947
948 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
949 hdev->le_pkts = rp->le_max_pkt;
950
951 hdev->le_cnt = hdev->le_pkts;
952
953 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
954
955 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
956}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200957
Johan Hedberga5c29682011-02-19 12:05:57 -0300958static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
959{
960 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
961
962 BT_DBG("%s status 0x%x", hdev->name, rp->status);
963
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200964 hci_dev_lock(hdev);
965
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200966 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200967 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
968 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200969
970 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300971}
972
973static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
974 struct sk_buff *skb)
975{
976 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
977
978 BT_DBG("%s status 0x%x", hdev->name, rp->status);
979
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200980 hci_dev_lock(hdev);
981
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200982 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200983 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200984 ACL_LINK, 0,
Johan Hedberga5c29682011-02-19 12:05:57 -0300985 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200986
987 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300988}
989
Brian Gix1143d452011-11-23 08:28:34 -0800990static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
991{
992 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
993
994 BT_DBG("%s status 0x%x", hdev->name, rp->status);
995
996 hci_dev_lock(hdev);
997
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200998 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200999 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1000 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001001
1002 hci_dev_unlock(hdev);
1003}
1004
1005static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1006 struct sk_buff *skb)
1007{
1008 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1009
1010 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1011
1012 hci_dev_lock(hdev);
1013
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001014 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001015 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001016 ACL_LINK, 0,
Brian Gix1143d452011-11-23 08:28:34 -08001017 rp->status);
1018
1019 hci_dev_unlock(hdev);
1020}
1021
Szymon Jancc35938b2011-03-22 13:12:21 +01001022static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1023 struct sk_buff *skb)
1024{
1025 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1026
1027 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1028
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001029 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001030 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001031 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001032 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001033}
1034
Andre Guedes07f7fa52011-12-02 21:13:31 +09001035static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1036{
1037 __u8 status = *((__u8 *) skb->data);
1038
1039 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001040
1041 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001042
1043 if (status) {
1044 hci_dev_lock(hdev);
1045 mgmt_start_discovery_failed(hdev, status);
1046 hci_dev_unlock(hdev);
1047 return;
1048 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001049}
1050
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001051static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1052 struct sk_buff *skb)
1053{
1054 struct hci_cp_le_set_scan_enable *cp;
1055 __u8 status = *((__u8 *) skb->data);
1056
1057 BT_DBG("%s status 0x%x", hdev->name, status);
1058
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001059 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1060 if (!cp)
1061 return;
1062
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001063 switch (cp->enable) {
1064 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001065 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1066
Andre Guedes3fd24152012-02-03 17:48:01 -03001067 if (status) {
1068 hci_dev_lock(hdev);
1069 mgmt_start_discovery_failed(hdev, status);
1070 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001071 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001072 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001073
Andre Guedesd23264a2011-11-25 20:53:38 -03001074 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1075
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001076 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001077
1078 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001079 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001080 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001081 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001082 break;
1083
1084 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001085 if (status)
1086 return;
1087
Andre Guedesd23264a2011-11-25 20:53:38 -03001088 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1089
Andre Guedesd0843292012-01-02 19:18:11 -03001090 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001091
1092 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1093 mgmt_interleaved_discovery(hdev);
1094 } else {
1095 hci_dev_lock(hdev);
1096 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1097 hci_dev_unlock(hdev);
1098 }
1099
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001100 break;
1101
1102 default:
1103 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1104 break;
Andre Guedes35815082011-05-26 16:23:53 -03001105 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001106}
1107
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001108static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1109{
1110 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1111
1112 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1113
1114 if (rp->status)
1115 return;
1116
1117 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1118}
1119
1120static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1121{
1122 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1123
1124 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1125
1126 if (rp->status)
1127 return;
1128
1129 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1130}
1131
Andre Guedesf9b49302011-06-30 19:20:53 -03001132static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1133 struct sk_buff *skb)
1134{
1135 struct hci_cp_read_local_ext_features cp;
1136 __u8 status = *((__u8 *) skb->data);
1137
1138 BT_DBG("%s status 0x%x", hdev->name, status);
1139
1140 if (status)
1141 return;
1142
1143 cp.page = 0x01;
1144 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1145}
1146
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001147static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1148{
1149 BT_DBG("%s status 0x%x", hdev->name, status);
1150
1151 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001152 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001153 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001154 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001155 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001156 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001157 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001158 return;
1159 }
1160
Andre Guedes89352e72011-11-04 14:16:53 -03001161 set_bit(HCI_INQUIRY, &hdev->flags);
1162
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001163 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001164 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001165 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001166}
1167
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1169{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001170 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001173 BT_DBG("%s status 0x%x", hdev->name, status);
1174
1175 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 if (!cp)
1177 return;
1178
1179 hci_dev_lock(hdev);
1180
1181 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1182
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001183 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184
1185 if (status) {
1186 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001187 if (status != 0x0c || conn->attempt > 2) {
1188 conn->state = BT_CLOSED;
1189 hci_proto_connect_cfm(conn, status);
1190 hci_conn_del(conn);
1191 } else
1192 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 }
1194 } else {
1195 if (!conn) {
1196 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1197 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001198 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199 conn->link_mode |= HCI_LM_MASTER;
1200 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001201 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 }
1203 }
1204
1205 hci_dev_unlock(hdev);
1206}
1207
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001208static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001210 struct hci_cp_add_sco *cp;
1211 struct hci_conn *acl, *sco;
1212 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001214 BT_DBG("%s status 0x%x", hdev->name, status);
1215
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001216 if (!status)
1217 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001219 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1220 if (!cp)
1221 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001223 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001225 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001226
1227 hci_dev_lock(hdev);
1228
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001229 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001230 if (acl) {
1231 sco = acl->link;
1232 if (sco) {
1233 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001234
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001235 hci_proto_connect_cfm(sco, status);
1236 hci_conn_del(sco);
1237 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001238 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001239
1240 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241}
1242
Marcel Holtmannf8558552008-07-14 20:13:49 +02001243static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1244{
1245 struct hci_cp_auth_requested *cp;
1246 struct hci_conn *conn;
1247
1248 BT_DBG("%s status 0x%x", hdev->name, status);
1249
1250 if (!status)
1251 return;
1252
1253 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1254 if (!cp)
1255 return;
1256
1257 hci_dev_lock(hdev);
1258
1259 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1260 if (conn) {
1261 if (conn->state == BT_CONFIG) {
1262 hci_proto_connect_cfm(conn, status);
1263 hci_conn_put(conn);
1264 }
1265 }
1266
1267 hci_dev_unlock(hdev);
1268}
1269
1270static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1271{
1272 struct hci_cp_set_conn_encrypt *cp;
1273 struct hci_conn *conn;
1274
1275 BT_DBG("%s status 0x%x", hdev->name, status);
1276
1277 if (!status)
1278 return;
1279
1280 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1281 if (!cp)
1282 return;
1283
1284 hci_dev_lock(hdev);
1285
1286 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1287 if (conn) {
1288 if (conn->state == BT_CONFIG) {
1289 hci_proto_connect_cfm(conn, status);
1290 hci_conn_put(conn);
1291 }
1292 }
1293
1294 hci_dev_unlock(hdev);
1295}
1296
Johan Hedberg127178d2010-11-18 22:22:29 +02001297static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001298 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001299{
Johan Hedberg392599b2010-11-18 22:22:28 +02001300 if (conn->state != BT_CONFIG || !conn->out)
1301 return 0;
1302
Johan Hedberg765c2a92011-01-19 12:06:52 +05301303 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001304 return 0;
1305
1306 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001307 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001308 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001309 conn->pending_sec_level != BT_SECURITY_HIGH &&
1310 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001311 return 0;
1312
Johan Hedberg392599b2010-11-18 22:22:28 +02001313 return 1;
1314}
1315
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001316static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1317{
1318 struct hci_cp_remote_name_req cp;
1319
1320 memset(&cp, 0, sizeof(cp));
1321
1322 bacpy(&cp.bdaddr, &e->data.bdaddr);
1323 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1324 cp.pscan_mode = e->data.pscan_mode;
1325 cp.clock_offset = e->data.clock_offset;
1326
1327 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1328}
1329
Johan Hedbergb644ba32012-01-17 21:48:47 +02001330static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001331{
1332 struct discovery_state *discov = &hdev->discovery;
1333 struct inquiry_entry *e;
1334
Johan Hedbergb644ba32012-01-17 21:48:47 +02001335 if (list_empty(&discov->resolve))
1336 return false;
1337
1338 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1339 if (hci_resolve_name(hdev, e) == 0) {
1340 e->name_state = NAME_PENDING;
1341 return true;
1342 }
1343
1344 return false;
1345}
1346
1347static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1348 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1349{
1350 struct discovery_state *discov = &hdev->discovery;
1351 struct inquiry_entry *e;
1352
1353 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1354 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
1355 name, name_len, conn->dev_class);
1356
1357 if (discov->state == DISCOVERY_STOPPED)
1358 return;
1359
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001360 if (discov->state == DISCOVERY_STOPPING)
1361 goto discov_complete;
1362
1363 if (discov->state != DISCOVERY_RESOLVING)
1364 return;
1365
1366 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1367 if (e) {
1368 e->name_state = NAME_KNOWN;
1369 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001370 if (name)
1371 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1372 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001373 }
1374
Johan Hedbergb644ba32012-01-17 21:48:47 +02001375 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001376 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001377
1378discov_complete:
1379 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1380}
1381
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001382static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1383{
Johan Hedberg127178d2010-11-18 22:22:29 +02001384 struct hci_cp_remote_name_req *cp;
1385 struct hci_conn *conn;
1386
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001387 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001388
1389 /* If successful wait for the name req complete event before
1390 * checking for the need to do authentication */
1391 if (!status)
1392 return;
1393
1394 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1395 if (!cp)
1396 return;
1397
1398 hci_dev_lock(hdev);
1399
1400 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001401
1402 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1403 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1404
Johan Hedberg79c6c702011-04-28 11:28:55 -07001405 if (!conn)
1406 goto unlock;
1407
1408 if (!hci_outgoing_auth_needed(hdev, conn))
1409 goto unlock;
1410
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001411 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001412 struct hci_cp_auth_requested cp;
1413 cp.handle = __cpu_to_le16(conn->handle);
1414 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1415 }
1416
Johan Hedberg79c6c702011-04-28 11:28:55 -07001417unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001418 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001419}
1420
Marcel Holtmann769be972008-07-14 20:13:49 +02001421static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1422{
1423 struct hci_cp_read_remote_features *cp;
1424 struct hci_conn *conn;
1425
1426 BT_DBG("%s status 0x%x", hdev->name, status);
1427
1428 if (!status)
1429 return;
1430
1431 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1432 if (!cp)
1433 return;
1434
1435 hci_dev_lock(hdev);
1436
1437 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1438 if (conn) {
1439 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001440 hci_proto_connect_cfm(conn, status);
1441 hci_conn_put(conn);
1442 }
1443 }
1444
1445 hci_dev_unlock(hdev);
1446}
1447
1448static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1449{
1450 struct hci_cp_read_remote_ext_features *cp;
1451 struct hci_conn *conn;
1452
1453 BT_DBG("%s status 0x%x", hdev->name, status);
1454
1455 if (!status)
1456 return;
1457
1458 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1459 if (!cp)
1460 return;
1461
1462 hci_dev_lock(hdev);
1463
1464 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1465 if (conn) {
1466 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001467 hci_proto_connect_cfm(conn, status);
1468 hci_conn_put(conn);
1469 }
1470 }
1471
1472 hci_dev_unlock(hdev);
1473}
1474
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001475static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1476{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001477 struct hci_cp_setup_sync_conn *cp;
1478 struct hci_conn *acl, *sco;
1479 __u16 handle;
1480
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001481 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001482
1483 if (!status)
1484 return;
1485
1486 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1487 if (!cp)
1488 return;
1489
1490 handle = __le16_to_cpu(cp->handle);
1491
1492 BT_DBG("%s handle %d", hdev->name, handle);
1493
1494 hci_dev_lock(hdev);
1495
1496 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001497 if (acl) {
1498 sco = acl->link;
1499 if (sco) {
1500 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001501
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001502 hci_proto_connect_cfm(sco, status);
1503 hci_conn_del(sco);
1504 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001505 }
1506
1507 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001508}
1509
1510static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1511{
1512 struct hci_cp_sniff_mode *cp;
1513 struct hci_conn *conn;
1514
1515 BT_DBG("%s status 0x%x", hdev->name, status);
1516
1517 if (!status)
1518 return;
1519
1520 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1521 if (!cp)
1522 return;
1523
1524 hci_dev_lock(hdev);
1525
1526 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001527 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001528 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001529
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001530 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001531 hci_sco_setup(conn, status);
1532 }
1533
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001534 hci_dev_unlock(hdev);
1535}
1536
1537static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1538{
1539 struct hci_cp_exit_sniff_mode *cp;
1540 struct hci_conn *conn;
1541
1542 BT_DBG("%s status 0x%x", hdev->name, status);
1543
1544 if (!status)
1545 return;
1546
1547 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1548 if (!cp)
1549 return;
1550
1551 hci_dev_lock(hdev);
1552
1553 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001554 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001555 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001556
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001557 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001558 hci_sco_setup(conn, status);
1559 }
1560
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001561 hci_dev_unlock(hdev);
1562}
1563
Johan Hedberg88c3df12012-02-09 14:27:38 +02001564static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1565{
1566 struct hci_cp_disconnect *cp;
1567 struct hci_conn *conn;
1568
1569 if (!status)
1570 return;
1571
1572 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1573 if (!cp)
1574 return;
1575
1576 hci_dev_lock(hdev);
1577
1578 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1579 if (conn)
1580 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1581 conn->dst_type, status);
1582
1583 hci_dev_unlock(hdev);
1584}
1585
Ville Tervofcd89c02011-02-10 22:38:47 -03001586static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1587{
1588 struct hci_cp_le_create_conn *cp;
1589 struct hci_conn *conn;
1590
1591 BT_DBG("%s status 0x%x", hdev->name, status);
1592
1593 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1594 if (!cp)
1595 return;
1596
1597 hci_dev_lock(hdev);
1598
1599 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1600
1601 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1602 conn);
1603
1604 if (status) {
1605 if (conn && conn->state == BT_CONNECT) {
1606 conn->state = BT_CLOSED;
1607 hci_proto_connect_cfm(conn, status);
1608 hci_conn_del(conn);
1609 }
1610 } else {
1611 if (!conn) {
1612 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001613 if (conn) {
1614 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001615 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001616 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001617 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001618 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001619 }
1620 }
1621
1622 hci_dev_unlock(hdev);
1623}
1624
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001625static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1626{
1627 BT_DBG("%s status 0x%x", hdev->name, status);
1628}
1629
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001630static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1631{
1632 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001633 struct discovery_state *discov = &hdev->discovery;
1634 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001635
1636 BT_DBG("%s status %d", hdev->name, status);
1637
Johan Hedberg23bb5762010-12-21 23:01:27 +02001638 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001639
1640 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001641
1642 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1643 return;
1644
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001645 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001646 return;
1647
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001648 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001649
Andre Guedes343f9352012-02-17 20:39:37 -03001650 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001651 goto unlock;
1652
1653 if (list_empty(&discov->resolve)) {
1654 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1655 goto unlock;
1656 }
1657
1658 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1659 if (e && hci_resolve_name(hdev, e) == 0) {
1660 e->name_state = NAME_PENDING;
1661 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1662 } else {
1663 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1664 }
1665
1666unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001667 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001668}
1669
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1671{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001672 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001673 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 int num_rsp = *((__u8 *) skb->data);
1675
1676 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1677
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001678 if (!num_rsp)
1679 return;
1680
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001682
Johan Hedberge17acd42011-03-30 23:57:16 +03001683 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg31754052012-01-04 13:39:52 +02001684 bool name_known;
1685
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 bacpy(&data.bdaddr, &info->bdaddr);
1687 data.pscan_rep_mode = info->pscan_rep_mode;
1688 data.pscan_period_mode = info->pscan_period_mode;
1689 data.pscan_mode = info->pscan_mode;
1690 memcpy(data.dev_class, info->dev_class, 3);
1691 data.clock_offset = info->clock_offset;
1692 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001693 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001694
1695 name_known = hci_inquiry_cache_update(hdev, &data, false);
Johan Hedberg48264f02011-11-09 13:58:58 +02001696 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Andre Guedes7d262f82012-01-10 18:20:49 -03001697 info->dev_class, 0, !name_known,
1698 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001700
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 hci_dev_unlock(hdev);
1702}
1703
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001704static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001706 struct hci_ev_conn_complete *ev = (void *) skb->data;
1707 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001709 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001710
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001712
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001713 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001714 if (!conn) {
1715 if (ev->link_type != SCO_LINK)
1716 goto unlock;
1717
1718 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1719 if (!conn)
1720 goto unlock;
1721
1722 conn->type = SCO_LINK;
1723 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001724
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001725 if (!ev->status) {
1726 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001727
1728 if (conn->type == ACL_LINK) {
1729 conn->state = BT_CONFIG;
1730 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001731 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001732 } else
1733 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001734
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001735 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001736 hci_conn_add_sysfs(conn);
1737
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001738 if (test_bit(HCI_AUTH, &hdev->flags))
1739 conn->link_mode |= HCI_LM_AUTH;
1740
1741 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1742 conn->link_mode |= HCI_LM_ENCRYPT;
1743
1744 /* Get remote features */
1745 if (conn->type == ACL_LINK) {
1746 struct hci_cp_read_remote_features cp;
1747 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001748 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1749 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001750 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001751
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001752 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001753 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001754 struct hci_cp_change_conn_ptype cp;
1755 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001756 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1757 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1758 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001759 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001760 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001761 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001762 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001763 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001764 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001765 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001766
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001767 if (conn->type == ACL_LINK)
1768 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001769
Marcel Holtmann769be972008-07-14 20:13:49 +02001770 if (ev->status) {
1771 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001772 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001773 } else if (ev->link_type != ACL_LINK)
1774 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001775
1776unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001778
1779 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780}
1781
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1783{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001784 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 int mask = hdev->link_mode;
1786
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001787 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1788 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789
1790 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1791
Szymon Janc138d22e2011-02-17 16:44:23 +01001792 if ((mask & HCI_LM_ACCEPT) &&
1793 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001795 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797
1798 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001799
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001800 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1801 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001802 memcpy(ie->data.dev_class, ev->dev_class, 3);
1803
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1805 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001806 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1807 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001808 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 hci_dev_unlock(hdev);
1810 return;
1811 }
1812 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001813
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 memcpy(conn->dev_class, ev->dev_class, 3);
1815 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001816
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 hci_dev_unlock(hdev);
1818
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001819 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1820 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001822 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001824 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1825 cp.role = 0x00; /* Become master */
1826 else
1827 cp.role = 0x01; /* Remain slave */
1828
1829 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1830 sizeof(cp), &cp);
1831 } else {
1832 struct hci_cp_accept_sync_conn_req cp;
1833
1834 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001835 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001836
1837 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1838 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1839 cp.max_latency = cpu_to_le16(0xffff);
1840 cp.content_format = cpu_to_le16(hdev->voice_setting);
1841 cp.retrans_effort = 0xff;
1842
1843 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1844 sizeof(cp), &cp);
1845 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 } else {
1847 /* Connection rejected */
1848 struct hci_cp_reject_conn_req cp;
1849
1850 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001851 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001852 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 }
1854}
1855
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1857{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001858 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001859 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
1861 BT_DBG("%s status %d", hdev->name, ev->status);
1862
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 hci_dev_lock(hdev);
1864
Marcel Holtmann04837f62006-07-03 10:02:33 +02001865 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001866 if (!conn)
1867 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001868
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001869 if (ev->status == 0)
1870 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871
Johan Hedbergb644ba32012-01-17 21:48:47 +02001872 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1873 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001874 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001875 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1876 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001877 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001878 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001879 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001880 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001881
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001882 if (ev->status == 0) {
1883 hci_proto_disconn_cfm(conn, ev->reason);
1884 hci_conn_del(conn);
1885 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001886
1887unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 hci_dev_unlock(hdev);
1889}
1890
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001891static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1892{
1893 struct hci_ev_auth_complete *ev = (void *) skb->data;
1894 struct hci_conn *conn;
1895
1896 BT_DBG("%s status %d", hdev->name, ev->status);
1897
1898 hci_dev_lock(hdev);
1899
1900 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001901 if (!conn)
1902 goto unlock;
1903
1904 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001905 if (!hci_conn_ssp_enabled(conn) &&
1906 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001907 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001908 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001909 conn->link_mode |= HCI_LM_AUTH;
1910 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001911 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001912 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001913 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
1914 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001915 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001916
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001917 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1918 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001919
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001920 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001921 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001922 struct hci_cp_set_conn_encrypt cp;
1923 cp.handle = ev->handle;
1924 cp.encrypt = 0x01;
1925 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1926 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001927 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001928 conn->state = BT_CONNECTED;
1929 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001930 hci_conn_put(conn);
1931 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001932 } else {
1933 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001934
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001935 hci_conn_hold(conn);
1936 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1937 hci_conn_put(conn);
1938 }
1939
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001940 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001941 if (!ev->status) {
1942 struct hci_cp_set_conn_encrypt cp;
1943 cp.handle = ev->handle;
1944 cp.encrypt = 0x01;
1945 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1946 &cp);
1947 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001948 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001949 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001950 }
1951 }
1952
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001953unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001954 hci_dev_unlock(hdev);
1955}
1956
1957static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1958{
Johan Hedberg127178d2010-11-18 22:22:29 +02001959 struct hci_ev_remote_name *ev = (void *) skb->data;
1960 struct hci_conn *conn;
1961
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001962 BT_DBG("%s", hdev->name);
1963
1964 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001965
1966 hci_dev_lock(hdev);
1967
1968 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001969
1970 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1971 goto check_auth;
1972
1973 if (ev->status == 0)
1974 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1975 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1976 else
1977 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1978
1979check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001980 if (!conn)
1981 goto unlock;
1982
1983 if (!hci_outgoing_auth_needed(hdev, conn))
1984 goto unlock;
1985
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001986 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001987 struct hci_cp_auth_requested cp;
1988 cp.handle = __cpu_to_le16(conn->handle);
1989 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1990 }
1991
Johan Hedberg79c6c702011-04-28 11:28:55 -07001992unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001993 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001994}
1995
1996static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1997{
1998 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1999 struct hci_conn *conn;
2000
2001 BT_DBG("%s status %d", hdev->name, ev->status);
2002
2003 hci_dev_lock(hdev);
2004
2005 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2006 if (conn) {
2007 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002008 if (ev->encrypt) {
2009 /* Encryption implies authentication */
2010 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002011 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002012 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002013 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002014 conn->link_mode &= ~HCI_LM_ENCRYPT;
2015 }
2016
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002017 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002018
Marcel Holtmannf8558552008-07-14 20:13:49 +02002019 if (conn->state == BT_CONFIG) {
2020 if (!ev->status)
2021 conn->state = BT_CONNECTED;
2022
2023 hci_proto_connect_cfm(conn, ev->status);
2024 hci_conn_put(conn);
2025 } else
2026 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002027 }
2028
2029 hci_dev_unlock(hdev);
2030}
2031
2032static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2033{
2034 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2035 struct hci_conn *conn;
2036
2037 BT_DBG("%s status %d", hdev->name, ev->status);
2038
2039 hci_dev_lock(hdev);
2040
2041 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2042 if (conn) {
2043 if (!ev->status)
2044 conn->link_mode |= HCI_LM_SECURE;
2045
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002046 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002047
2048 hci_key_change_cfm(conn, ev->status);
2049 }
2050
2051 hci_dev_unlock(hdev);
2052}
2053
2054static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2055{
2056 struct hci_ev_remote_features *ev = (void *) skb->data;
2057 struct hci_conn *conn;
2058
2059 BT_DBG("%s status %d", hdev->name, ev->status);
2060
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002061 hci_dev_lock(hdev);
2062
2063 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002064 if (!conn)
2065 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002066
Johan Hedbergccd556f2010-11-10 17:11:51 +02002067 if (!ev->status)
2068 memcpy(conn->features, ev->features, 8);
2069
2070 if (conn->state != BT_CONFIG)
2071 goto unlock;
2072
2073 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2074 struct hci_cp_read_remote_ext_features cp;
2075 cp.handle = ev->handle;
2076 cp.page = 0x01;
2077 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002078 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002079 goto unlock;
2080 }
2081
Johan Hedberg127178d2010-11-18 22:22:29 +02002082 if (!ev->status) {
2083 struct hci_cp_remote_name_req cp;
2084 memset(&cp, 0, sizeof(cp));
2085 bacpy(&cp.bdaddr, &conn->dst);
2086 cp.pscan_rep_mode = 0x02;
2087 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002088 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2089 mgmt_device_connected(hdev, &conn->dst, conn->type,
2090 conn->dst_type, NULL, 0,
2091 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002092
Johan Hedberg127178d2010-11-18 22:22:29 +02002093 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002094 conn->state = BT_CONNECTED;
2095 hci_proto_connect_cfm(conn, ev->status);
2096 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002097 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002098
Johan Hedbergccd556f2010-11-10 17:11:51 +02002099unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002100 hci_dev_unlock(hdev);
2101}
2102
2103static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2104{
2105 BT_DBG("%s", hdev->name);
2106}
2107
2108static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2109{
2110 BT_DBG("%s", hdev->name);
2111}
2112
2113static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2114{
2115 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2116 __u16 opcode;
2117
2118 skb_pull(skb, sizeof(*ev));
2119
2120 opcode = __le16_to_cpu(ev->opcode);
2121
2122 switch (opcode) {
2123 case HCI_OP_INQUIRY_CANCEL:
2124 hci_cc_inquiry_cancel(hdev, skb);
2125 break;
2126
2127 case HCI_OP_EXIT_PERIODIC_INQ:
2128 hci_cc_exit_periodic_inq(hdev, skb);
2129 break;
2130
2131 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2132 hci_cc_remote_name_req_cancel(hdev, skb);
2133 break;
2134
2135 case HCI_OP_ROLE_DISCOVERY:
2136 hci_cc_role_discovery(hdev, skb);
2137 break;
2138
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002139 case HCI_OP_READ_LINK_POLICY:
2140 hci_cc_read_link_policy(hdev, skb);
2141 break;
2142
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002143 case HCI_OP_WRITE_LINK_POLICY:
2144 hci_cc_write_link_policy(hdev, skb);
2145 break;
2146
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002147 case HCI_OP_READ_DEF_LINK_POLICY:
2148 hci_cc_read_def_link_policy(hdev, skb);
2149 break;
2150
2151 case HCI_OP_WRITE_DEF_LINK_POLICY:
2152 hci_cc_write_def_link_policy(hdev, skb);
2153 break;
2154
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002155 case HCI_OP_RESET:
2156 hci_cc_reset(hdev, skb);
2157 break;
2158
2159 case HCI_OP_WRITE_LOCAL_NAME:
2160 hci_cc_write_local_name(hdev, skb);
2161 break;
2162
2163 case HCI_OP_READ_LOCAL_NAME:
2164 hci_cc_read_local_name(hdev, skb);
2165 break;
2166
2167 case HCI_OP_WRITE_AUTH_ENABLE:
2168 hci_cc_write_auth_enable(hdev, skb);
2169 break;
2170
2171 case HCI_OP_WRITE_ENCRYPT_MODE:
2172 hci_cc_write_encrypt_mode(hdev, skb);
2173 break;
2174
2175 case HCI_OP_WRITE_SCAN_ENABLE:
2176 hci_cc_write_scan_enable(hdev, skb);
2177 break;
2178
2179 case HCI_OP_READ_CLASS_OF_DEV:
2180 hci_cc_read_class_of_dev(hdev, skb);
2181 break;
2182
2183 case HCI_OP_WRITE_CLASS_OF_DEV:
2184 hci_cc_write_class_of_dev(hdev, skb);
2185 break;
2186
2187 case HCI_OP_READ_VOICE_SETTING:
2188 hci_cc_read_voice_setting(hdev, skb);
2189 break;
2190
2191 case HCI_OP_WRITE_VOICE_SETTING:
2192 hci_cc_write_voice_setting(hdev, skb);
2193 break;
2194
2195 case HCI_OP_HOST_BUFFER_SIZE:
2196 hci_cc_host_buffer_size(hdev, skb);
2197 break;
2198
Marcel Holtmann333140b2008-07-14 20:13:48 +02002199 case HCI_OP_READ_SSP_MODE:
2200 hci_cc_read_ssp_mode(hdev, skb);
2201 break;
2202
2203 case HCI_OP_WRITE_SSP_MODE:
2204 hci_cc_write_ssp_mode(hdev, skb);
2205 break;
2206
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002207 case HCI_OP_READ_LOCAL_VERSION:
2208 hci_cc_read_local_version(hdev, skb);
2209 break;
2210
2211 case HCI_OP_READ_LOCAL_COMMANDS:
2212 hci_cc_read_local_commands(hdev, skb);
2213 break;
2214
2215 case HCI_OP_READ_LOCAL_FEATURES:
2216 hci_cc_read_local_features(hdev, skb);
2217 break;
2218
Andre Guedes971e3a42011-06-30 19:20:52 -03002219 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2220 hci_cc_read_local_ext_features(hdev, skb);
2221 break;
2222
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002223 case HCI_OP_READ_BUFFER_SIZE:
2224 hci_cc_read_buffer_size(hdev, skb);
2225 break;
2226
2227 case HCI_OP_READ_BD_ADDR:
2228 hci_cc_read_bd_addr(hdev, skb);
2229 break;
2230
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002231 case HCI_OP_READ_DATA_BLOCK_SIZE:
2232 hci_cc_read_data_block_size(hdev, skb);
2233 break;
2234
Johan Hedberg23bb5762010-12-21 23:01:27 +02002235 case HCI_OP_WRITE_CA_TIMEOUT:
2236 hci_cc_write_ca_timeout(hdev, skb);
2237 break;
2238
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002239 case HCI_OP_READ_FLOW_CONTROL_MODE:
2240 hci_cc_read_flow_control_mode(hdev, skb);
2241 break;
2242
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002243 case HCI_OP_READ_LOCAL_AMP_INFO:
2244 hci_cc_read_local_amp_info(hdev, skb);
2245 break;
2246
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002247 case HCI_OP_DELETE_STORED_LINK_KEY:
2248 hci_cc_delete_stored_link_key(hdev, skb);
2249 break;
2250
Johan Hedbergd5859e22011-01-25 01:19:58 +02002251 case HCI_OP_SET_EVENT_MASK:
2252 hci_cc_set_event_mask(hdev, skb);
2253 break;
2254
2255 case HCI_OP_WRITE_INQUIRY_MODE:
2256 hci_cc_write_inquiry_mode(hdev, skb);
2257 break;
2258
2259 case HCI_OP_READ_INQ_RSP_TX_POWER:
2260 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2261 break;
2262
2263 case HCI_OP_SET_EVENT_FLT:
2264 hci_cc_set_event_flt(hdev, skb);
2265 break;
2266
Johan Hedberg980e1a52011-01-22 06:10:07 +02002267 case HCI_OP_PIN_CODE_REPLY:
2268 hci_cc_pin_code_reply(hdev, skb);
2269 break;
2270
2271 case HCI_OP_PIN_CODE_NEG_REPLY:
2272 hci_cc_pin_code_neg_reply(hdev, skb);
2273 break;
2274
Szymon Jancc35938b2011-03-22 13:12:21 +01002275 case HCI_OP_READ_LOCAL_OOB_DATA:
2276 hci_cc_read_local_oob_data_reply(hdev, skb);
2277 break;
2278
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002279 case HCI_OP_LE_READ_BUFFER_SIZE:
2280 hci_cc_le_read_buffer_size(hdev, skb);
2281 break;
2282
Johan Hedberga5c29682011-02-19 12:05:57 -03002283 case HCI_OP_USER_CONFIRM_REPLY:
2284 hci_cc_user_confirm_reply(hdev, skb);
2285 break;
2286
2287 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2288 hci_cc_user_confirm_neg_reply(hdev, skb);
2289 break;
2290
Brian Gix1143d452011-11-23 08:28:34 -08002291 case HCI_OP_USER_PASSKEY_REPLY:
2292 hci_cc_user_passkey_reply(hdev, skb);
2293 break;
2294
2295 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2296 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002297
2298 case HCI_OP_LE_SET_SCAN_PARAM:
2299 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002300 break;
2301
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002302 case HCI_OP_LE_SET_SCAN_ENABLE:
2303 hci_cc_le_set_scan_enable(hdev, skb);
2304 break;
2305
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002306 case HCI_OP_LE_LTK_REPLY:
2307 hci_cc_le_ltk_reply(hdev, skb);
2308 break;
2309
2310 case HCI_OP_LE_LTK_NEG_REPLY:
2311 hci_cc_le_ltk_neg_reply(hdev, skb);
2312 break;
2313
Andre Guedesf9b49302011-06-30 19:20:53 -03002314 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2315 hci_cc_write_le_host_supported(hdev, skb);
2316 break;
2317
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002318 default:
2319 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2320 break;
2321 }
2322
Ville Tervo6bd32322011-02-16 16:32:41 +02002323 if (ev->opcode != HCI_OP_NOP)
2324 del_timer(&hdev->cmd_timer);
2325
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002326 if (ev->ncmd) {
2327 atomic_set(&hdev->cmd_cnt, 1);
2328 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002329 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002330 }
2331}
2332
2333static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2334{
2335 struct hci_ev_cmd_status *ev = (void *) skb->data;
2336 __u16 opcode;
2337
2338 skb_pull(skb, sizeof(*ev));
2339
2340 opcode = __le16_to_cpu(ev->opcode);
2341
2342 switch (opcode) {
2343 case HCI_OP_INQUIRY:
2344 hci_cs_inquiry(hdev, ev->status);
2345 break;
2346
2347 case HCI_OP_CREATE_CONN:
2348 hci_cs_create_conn(hdev, ev->status);
2349 break;
2350
2351 case HCI_OP_ADD_SCO:
2352 hci_cs_add_sco(hdev, ev->status);
2353 break;
2354
Marcel Holtmannf8558552008-07-14 20:13:49 +02002355 case HCI_OP_AUTH_REQUESTED:
2356 hci_cs_auth_requested(hdev, ev->status);
2357 break;
2358
2359 case HCI_OP_SET_CONN_ENCRYPT:
2360 hci_cs_set_conn_encrypt(hdev, ev->status);
2361 break;
2362
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002363 case HCI_OP_REMOTE_NAME_REQ:
2364 hci_cs_remote_name_req(hdev, ev->status);
2365 break;
2366
Marcel Holtmann769be972008-07-14 20:13:49 +02002367 case HCI_OP_READ_REMOTE_FEATURES:
2368 hci_cs_read_remote_features(hdev, ev->status);
2369 break;
2370
2371 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2372 hci_cs_read_remote_ext_features(hdev, ev->status);
2373 break;
2374
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002375 case HCI_OP_SETUP_SYNC_CONN:
2376 hci_cs_setup_sync_conn(hdev, ev->status);
2377 break;
2378
2379 case HCI_OP_SNIFF_MODE:
2380 hci_cs_sniff_mode(hdev, ev->status);
2381 break;
2382
2383 case HCI_OP_EXIT_SNIFF_MODE:
2384 hci_cs_exit_sniff_mode(hdev, ev->status);
2385 break;
2386
Johan Hedberg8962ee72011-01-20 12:40:27 +02002387 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002388 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002389 break;
2390
Ville Tervofcd89c02011-02-10 22:38:47 -03002391 case HCI_OP_LE_CREATE_CONN:
2392 hci_cs_le_create_conn(hdev, ev->status);
2393 break;
2394
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002395 case HCI_OP_LE_START_ENC:
2396 hci_cs_le_start_enc(hdev, ev->status);
2397 break;
2398
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002399 default:
2400 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2401 break;
2402 }
2403
Ville Tervo6bd32322011-02-16 16:32:41 +02002404 if (ev->opcode != HCI_OP_NOP)
2405 del_timer(&hdev->cmd_timer);
2406
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002407 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002408 atomic_set(&hdev->cmd_cnt, 1);
2409 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002410 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002411 }
2412}
2413
2414static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2415{
2416 struct hci_ev_role_change *ev = (void *) skb->data;
2417 struct hci_conn *conn;
2418
2419 BT_DBG("%s status %d", hdev->name, ev->status);
2420
2421 hci_dev_lock(hdev);
2422
2423 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2424 if (conn) {
2425 if (!ev->status) {
2426 if (ev->role)
2427 conn->link_mode &= ~HCI_LM_MASTER;
2428 else
2429 conn->link_mode |= HCI_LM_MASTER;
2430 }
2431
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002432 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002433
2434 hci_role_switch_cfm(conn, ev->status, ev->role);
2435 }
2436
2437 hci_dev_unlock(hdev);
2438}
2439
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2441{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002442 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002443 int i;
2444
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002445 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2446 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2447 return;
2448 }
2449
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002450 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2451 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002452 BT_DBG("%s bad parameters", hdev->name);
2453 return;
2454 }
2455
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002456 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2457
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002458 for (i = 0; i < ev->num_hndl; i++) {
2459 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460 struct hci_conn *conn;
2461 __u16 handle, count;
2462
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002463 handle = __le16_to_cpu(info->handle);
2464 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002465
2466 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002467 if (!conn)
2468 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002469
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002470 conn->sent -= count;
2471
2472 switch (conn->type) {
2473 case ACL_LINK:
2474 hdev->acl_cnt += count;
2475 if (hdev->acl_cnt > hdev->acl_pkts)
2476 hdev->acl_cnt = hdev->acl_pkts;
2477 break;
2478
2479 case LE_LINK:
2480 if (hdev->le_pkts) {
2481 hdev->le_cnt += count;
2482 if (hdev->le_cnt > hdev->le_pkts)
2483 hdev->le_cnt = hdev->le_pkts;
2484 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002485 hdev->acl_cnt += count;
2486 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487 hdev->acl_cnt = hdev->acl_pkts;
2488 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002489 break;
2490
2491 case SCO_LINK:
2492 hdev->sco_cnt += count;
2493 if (hdev->sco_cnt > hdev->sco_pkts)
2494 hdev->sco_cnt = hdev->sco_pkts;
2495 break;
2496
2497 default:
2498 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2499 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500 }
2501 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002502
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002503 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504}
2505
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002506static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2507 struct sk_buff *skb)
2508{
2509 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2510 int i;
2511
2512 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2513 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2514 return;
2515 }
2516
2517 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2518 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2519 BT_DBG("%s bad parameters", hdev->name);
2520 return;
2521 }
2522
2523 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2524 ev->num_hndl);
2525
2526 for (i = 0; i < ev->num_hndl; i++) {
2527 struct hci_comp_blocks_info *info = &ev->handles[i];
2528 struct hci_conn *conn;
2529 __u16 handle, block_count;
2530
2531 handle = __le16_to_cpu(info->handle);
2532 block_count = __le16_to_cpu(info->blocks);
2533
2534 conn = hci_conn_hash_lookup_handle(hdev, handle);
2535 if (!conn)
2536 continue;
2537
2538 conn->sent -= block_count;
2539
2540 switch (conn->type) {
2541 case ACL_LINK:
2542 hdev->block_cnt += block_count;
2543 if (hdev->block_cnt > hdev->num_blocks)
2544 hdev->block_cnt = hdev->num_blocks;
2545 break;
2546
2547 default:
2548 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2549 break;
2550 }
2551 }
2552
2553 queue_work(hdev->workqueue, &hdev->tx_work);
2554}
2555
Marcel Holtmann04837f62006-07-03 10:02:33 +02002556static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002558 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002559 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560
2561 BT_DBG("%s status %d", hdev->name, ev->status);
2562
2563 hci_dev_lock(hdev);
2564
Marcel Holtmann04837f62006-07-03 10:02:33 +02002565 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2566 if (conn) {
2567 conn->mode = ev->mode;
2568 conn->interval = __le16_to_cpu(ev->interval);
2569
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002570 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002571 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002572 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002573 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002574 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002575 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002576
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002577 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002578 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002579 }
2580
2581 hci_dev_unlock(hdev);
2582}
2583
Linus Torvalds1da177e2005-04-16 15:20:36 -07002584static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2585{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002586 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2587 struct hci_conn *conn;
2588
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002589 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002590
2591 hci_dev_lock(hdev);
2592
2593 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002594 if (!conn)
2595 goto unlock;
2596
2597 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002598 hci_conn_hold(conn);
2599 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2600 hci_conn_put(conn);
2601 }
2602
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002603 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002604 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2605 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002606 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002607 u8 secure;
2608
2609 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2610 secure = 1;
2611 else
2612 secure = 0;
2613
Johan Hedberg744cf192011-11-08 20:40:14 +02002614 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002615 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002616
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002617unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002618 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619}
2620
Linus Torvalds1da177e2005-04-16 15:20:36 -07002621static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2622{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002623 struct hci_ev_link_key_req *ev = (void *) skb->data;
2624 struct hci_cp_link_key_reply cp;
2625 struct hci_conn *conn;
2626 struct link_key *key;
2627
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002628 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002629
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002630 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002631 return;
2632
2633 hci_dev_lock(hdev);
2634
2635 key = hci_find_link_key(hdev, &ev->bdaddr);
2636 if (!key) {
2637 BT_DBG("%s link key not found for %s", hdev->name,
2638 batostr(&ev->bdaddr));
2639 goto not_found;
2640 }
2641
2642 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2643 batostr(&ev->bdaddr));
2644
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002645 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002646 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002647 BT_DBG("%s ignoring debug key", hdev->name);
2648 goto not_found;
2649 }
2650
2651 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002652 if (conn) {
2653 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2654 conn->auth_type != 0xff &&
2655 (conn->auth_type & 0x01)) {
2656 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2657 goto not_found;
2658 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002659
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002660 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2661 conn->pending_sec_level == BT_SECURITY_HIGH) {
2662 BT_DBG("%s ignoring key unauthenticated for high \
2663 security", hdev->name);
2664 goto not_found;
2665 }
2666
2667 conn->key_type = key->type;
2668 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002669 }
2670
2671 bacpy(&cp.bdaddr, &ev->bdaddr);
2672 memcpy(cp.link_key, key->val, 16);
2673
2674 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2675
2676 hci_dev_unlock(hdev);
2677
2678 return;
2679
2680not_found:
2681 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2682 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683}
2684
Linus Torvalds1da177e2005-04-16 15:20:36 -07002685static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2686{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002687 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2688 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002689 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002690
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002691 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002692
2693 hci_dev_lock(hdev);
2694
2695 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2696 if (conn) {
2697 hci_conn_hold(conn);
2698 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002699 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002700
2701 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2702 conn->key_type = ev->key_type;
2703
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002704 hci_conn_put(conn);
2705 }
2706
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002707 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002708 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002709 ev->key_type, pin_len);
2710
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002711 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002712}
2713
Marcel Holtmann04837f62006-07-03 10:02:33 +02002714static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2715{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002716 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002717 struct hci_conn *conn;
2718
2719 BT_DBG("%s status %d", hdev->name, ev->status);
2720
2721 hci_dev_lock(hdev);
2722
2723 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002724 if (conn && !ev->status) {
2725 struct inquiry_entry *ie;
2726
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002727 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2728 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002729 ie->data.clock_offset = ev->clock_offset;
2730 ie->timestamp = jiffies;
2731 }
2732 }
2733
2734 hci_dev_unlock(hdev);
2735}
2736
Marcel Holtmanna8746412008-07-14 20:13:46 +02002737static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2738{
2739 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2740 struct hci_conn *conn;
2741
2742 BT_DBG("%s status %d", hdev->name, ev->status);
2743
2744 hci_dev_lock(hdev);
2745
2746 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2747 if (conn && !ev->status)
2748 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2749
2750 hci_dev_unlock(hdev);
2751}
2752
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002753static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2754{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002755 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002756 struct inquiry_entry *ie;
2757
2758 BT_DBG("%s", hdev->name);
2759
2760 hci_dev_lock(hdev);
2761
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002762 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2763 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002764 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2765 ie->timestamp = jiffies;
2766 }
2767
2768 hci_dev_unlock(hdev);
2769}
2770
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002771static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2772{
2773 struct inquiry_data data;
2774 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg31754052012-01-04 13:39:52 +02002775 bool name_known;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002776
2777 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2778
2779 if (!num_rsp)
2780 return;
2781
2782 hci_dev_lock(hdev);
2783
2784 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002785 struct inquiry_info_with_rssi_and_pscan_mode *info;
2786 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002787
Johan Hedberge17acd42011-03-30 23:57:16 +03002788 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002789 bacpy(&data.bdaddr, &info->bdaddr);
2790 data.pscan_rep_mode = info->pscan_rep_mode;
2791 data.pscan_period_mode = info->pscan_period_mode;
2792 data.pscan_mode = info->pscan_mode;
2793 memcpy(data.dev_class, info->dev_class, 3);
2794 data.clock_offset = info->clock_offset;
2795 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002796 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002797
2798 name_known = hci_inquiry_cache_update(hdev, &data,
2799 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002800 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002801 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002802 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002803 }
2804 } else {
2805 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2806
Johan Hedberge17acd42011-03-30 23:57:16 +03002807 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002808 bacpy(&data.bdaddr, &info->bdaddr);
2809 data.pscan_rep_mode = info->pscan_rep_mode;
2810 data.pscan_period_mode = info->pscan_period_mode;
2811 data.pscan_mode = 0x00;
2812 memcpy(data.dev_class, info->dev_class, 3);
2813 data.clock_offset = info->clock_offset;
2814 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002815 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002816 name_known = hci_inquiry_cache_update(hdev, &data,
2817 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002818 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002819 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002820 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002821 }
2822 }
2823
2824 hci_dev_unlock(hdev);
2825}
2826
2827static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2828{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002829 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2830 struct hci_conn *conn;
2831
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002832 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002833
Marcel Holtmann41a96212008-07-14 20:13:48 +02002834 hci_dev_lock(hdev);
2835
2836 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002837 if (!conn)
2838 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002839
Johan Hedbergccd556f2010-11-10 17:11:51 +02002840 if (!ev->status && ev->page == 0x01) {
2841 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002842
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002843 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2844 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002845 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002846
Johan Hedberg58a681e2012-01-16 06:47:28 +02002847 if (ev->features[0] & 0x01)
2848 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002849 }
2850
Johan Hedbergccd556f2010-11-10 17:11:51 +02002851 if (conn->state != BT_CONFIG)
2852 goto unlock;
2853
Johan Hedberg127178d2010-11-18 22:22:29 +02002854 if (!ev->status) {
2855 struct hci_cp_remote_name_req cp;
2856 memset(&cp, 0, sizeof(cp));
2857 bacpy(&cp.bdaddr, &conn->dst);
2858 cp.pscan_rep_mode = 0x02;
2859 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002860 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2861 mgmt_device_connected(hdev, &conn->dst, conn->type,
2862 conn->dst_type, NULL, 0,
2863 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002864
Johan Hedberg127178d2010-11-18 22:22:29 +02002865 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002866 conn->state = BT_CONNECTED;
2867 hci_proto_connect_cfm(conn, ev->status);
2868 hci_conn_put(conn);
2869 }
2870
2871unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002872 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002873}
2874
2875static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2876{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002877 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2878 struct hci_conn *conn;
2879
2880 BT_DBG("%s status %d", hdev->name, ev->status);
2881
2882 hci_dev_lock(hdev);
2883
2884 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002885 if (!conn) {
2886 if (ev->link_type == ESCO_LINK)
2887 goto unlock;
2888
2889 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2890 if (!conn)
2891 goto unlock;
2892
2893 conn->type = SCO_LINK;
2894 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002895
Marcel Holtmann732547f2009-04-19 19:14:14 +02002896 switch (ev->status) {
2897 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002898 conn->handle = __le16_to_cpu(ev->handle);
2899 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002900
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002901 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002902 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002903 break;
2904
Stephen Coe705e5712010-02-16 11:29:44 -05002905 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002906 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002907 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002908 case 0x1f: /* Unspecified error */
2909 if (conn->out && conn->attempt < 2) {
2910 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2911 (hdev->esco_type & EDR_ESCO_MASK);
2912 hci_setup_sync(conn, conn->link->handle);
2913 goto unlock;
2914 }
2915 /* fall through */
2916
2917 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002918 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002919 break;
2920 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002921
2922 hci_proto_connect_cfm(conn, ev->status);
2923 if (ev->status)
2924 hci_conn_del(conn);
2925
2926unlock:
2927 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002928}
2929
2930static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2931{
2932 BT_DBG("%s", hdev->name);
2933}
2934
Marcel Holtmann04837f62006-07-03 10:02:33 +02002935static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2936{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002937 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002938
2939 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002940}
2941
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002942static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2943{
2944 struct inquiry_data data;
2945 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2946 int num_rsp = *((__u8 *) skb->data);
2947
2948 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2949
2950 if (!num_rsp)
2951 return;
2952
2953 hci_dev_lock(hdev);
2954
Johan Hedberge17acd42011-03-30 23:57:16 +03002955 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg561aafb2012-01-04 13:31:59 +02002956 bool name_known;
2957
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002958 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002959 data.pscan_rep_mode = info->pscan_rep_mode;
2960 data.pscan_period_mode = info->pscan_period_mode;
2961 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002962 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002963 data.clock_offset = info->clock_offset;
2964 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002965 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002966
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002967 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002968 name_known = eir_has_data_type(info->data,
2969 sizeof(info->data),
2970 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002971 else
2972 name_known = true;
2973
Johan Hedberg31754052012-01-04 13:39:52 +02002974 name_known = hci_inquiry_cache_update(hdev, &data, name_known);
Johan Hedberg48264f02011-11-09 13:58:58 +02002975 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002976 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002977 !name_known, info->data,
2978 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002979 }
2980
2981 hci_dev_unlock(hdev);
2982}
2983
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002984static inline u8 hci_get_auth_req(struct hci_conn *conn)
2985{
2986 /* If remote requests dedicated bonding follow that lead */
2987 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2988 /* If both remote and local IO capabilities allow MITM
2989 * protection then require it, otherwise don't */
2990 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2991 return 0x02;
2992 else
2993 return 0x03;
2994 }
2995
2996 /* If remote requests no-bonding follow that lead */
2997 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002998 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002999
3000 return conn->auth_type;
3001}
3002
Marcel Holtmann04936842008-07-14 20:13:48 +02003003static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3004{
3005 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3006 struct hci_conn *conn;
3007
3008 BT_DBG("%s", hdev->name);
3009
3010 hci_dev_lock(hdev);
3011
3012 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003013 if (!conn)
3014 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003015
Johan Hedberg03b555e2011-01-04 15:40:05 +02003016 hci_conn_hold(conn);
3017
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003018 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003019 goto unlock;
3020
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003021 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003022 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003023 struct hci_cp_io_capability_reply cp;
3024
3025 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303026 /* Change the IO capability from KeyboardDisplay
3027 * to DisplayYesNo as it is not supported by BT spec. */
3028 cp.capability = (conn->io_capability == 0x04) ?
3029 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003030 conn->auth_type = hci_get_auth_req(conn);
3031 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003032
Johan Hedberg58a681e2012-01-16 06:47:28 +02003033 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003034 hci_find_remote_oob_data(hdev, &conn->dst))
3035 cp.oob_data = 0x01;
3036 else
3037 cp.oob_data = 0x00;
3038
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003039 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3040 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003041 } else {
3042 struct hci_cp_io_capability_neg_reply cp;
3043
3044 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003045 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003046
3047 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3048 sizeof(cp), &cp);
3049 }
3050
3051unlock:
3052 hci_dev_unlock(hdev);
3053}
3054
3055static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3056{
3057 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3058 struct hci_conn *conn;
3059
3060 BT_DBG("%s", hdev->name);
3061
3062 hci_dev_lock(hdev);
3063
3064 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3065 if (!conn)
3066 goto unlock;
3067
Johan Hedberg03b555e2011-01-04 15:40:05 +02003068 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003069 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003070 if (ev->oob_data)
3071 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003072
3073unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003074 hci_dev_unlock(hdev);
3075}
3076
Johan Hedberga5c29682011-02-19 12:05:57 -03003077static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3078 struct sk_buff *skb)
3079{
3080 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003081 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003082 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003083
3084 BT_DBG("%s", hdev->name);
3085
3086 hci_dev_lock(hdev);
3087
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003088 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003089 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003090
Johan Hedberg7a828902011-04-28 11:28:53 -07003091 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3092 if (!conn)
3093 goto unlock;
3094
3095 loc_mitm = (conn->auth_type & 0x01);
3096 rem_mitm = (conn->remote_auth & 0x01);
3097
3098 /* If we require MITM but the remote device can't provide that
3099 * (it has NoInputNoOutput) then reject the confirmation
3100 * request. The only exception is when we're dedicated bonding
3101 * initiators (connect_cfm_cb set) since then we always have the MITM
3102 * bit set. */
3103 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3104 BT_DBG("Rejecting request: remote device can't provide MITM");
3105 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3106 sizeof(ev->bdaddr), &ev->bdaddr);
3107 goto unlock;
3108 }
3109
3110 /* If no side requires MITM protection; auto-accept */
3111 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3112 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003113
3114 /* If we're not the initiators request authorization to
3115 * proceed from user space (mgmt_user_confirm with
3116 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003117 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003118 BT_DBG("Confirming auto-accept as acceptor");
3119 confirm_hint = 1;
3120 goto confirm;
3121 }
3122
Johan Hedberg9f616562011-04-28 11:28:54 -07003123 BT_DBG("Auto-accept of user confirmation with %ums delay",
3124 hdev->auto_accept_delay);
3125
3126 if (hdev->auto_accept_delay > 0) {
3127 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3128 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3129 goto unlock;
3130 }
3131
Johan Hedberg7a828902011-04-28 11:28:53 -07003132 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3133 sizeof(ev->bdaddr), &ev->bdaddr);
3134 goto unlock;
3135 }
3136
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003137confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003138 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003139 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003140
3141unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003142 hci_dev_unlock(hdev);
3143}
3144
Brian Gix1143d452011-11-23 08:28:34 -08003145static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3146 struct sk_buff *skb)
3147{
3148 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3149
3150 BT_DBG("%s", hdev->name);
3151
3152 hci_dev_lock(hdev);
3153
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003154 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003155 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003156
3157 hci_dev_unlock(hdev);
3158}
3159
Marcel Holtmann04936842008-07-14 20:13:48 +02003160static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3161{
3162 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3163 struct hci_conn *conn;
3164
3165 BT_DBG("%s", hdev->name);
3166
3167 hci_dev_lock(hdev);
3168
3169 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003170 if (!conn)
3171 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003172
Johan Hedberg2a611692011-02-19 12:06:00 -03003173 /* To avoid duplicate auth_failed events to user space we check
3174 * the HCI_CONN_AUTH_PEND flag which will be set if we
3175 * initiated the authentication. A traditional auth_complete
3176 * event gets always produced as initiator and is also mapped to
3177 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003178 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003179 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3180 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003181
3182 hci_conn_put(conn);
3183
3184unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003185 hci_dev_unlock(hdev);
3186}
3187
Marcel Holtmann41a96212008-07-14 20:13:48 +02003188static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3189{
3190 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3191 struct inquiry_entry *ie;
3192
3193 BT_DBG("%s", hdev->name);
3194
3195 hci_dev_lock(hdev);
3196
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003197 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3198 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003199 ie->data.ssp_mode = (ev->features[0] & 0x01);
3200
3201 hci_dev_unlock(hdev);
3202}
3203
Szymon Janc2763eda2011-03-22 13:12:22 +01003204static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3205 struct sk_buff *skb)
3206{
3207 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3208 struct oob_data *data;
3209
3210 BT_DBG("%s", hdev->name);
3211
3212 hci_dev_lock(hdev);
3213
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003214 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003215 goto unlock;
3216
Szymon Janc2763eda2011-03-22 13:12:22 +01003217 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3218 if (data) {
3219 struct hci_cp_remote_oob_data_reply cp;
3220
3221 bacpy(&cp.bdaddr, &ev->bdaddr);
3222 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3223 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3224
3225 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3226 &cp);
3227 } else {
3228 struct hci_cp_remote_oob_data_neg_reply cp;
3229
3230 bacpy(&cp.bdaddr, &ev->bdaddr);
3231 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3232 &cp);
3233 }
3234
Szymon Jance1ba1f12011-04-06 13:01:59 +02003235unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003236 hci_dev_unlock(hdev);
3237}
3238
Ville Tervofcd89c02011-02-10 22:38:47 -03003239static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3240{
3241 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3242 struct hci_conn *conn;
3243
3244 BT_DBG("%s status %d", hdev->name, ev->status);
3245
3246 hci_dev_lock(hdev);
3247
3248 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003249 if (!conn) {
3250 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3251 if (!conn) {
3252 BT_ERR("No memory for new connection");
3253 hci_dev_unlock(hdev);
3254 return;
3255 }
Andre Guedes29b79882011-05-31 14:20:54 -03003256
3257 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003258 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003259
3260 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003261 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3262 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003263 hci_proto_connect_cfm(conn, ev->status);
3264 conn->state = BT_CLOSED;
3265 hci_conn_del(conn);
3266 goto unlock;
3267 }
3268
Johan Hedbergb644ba32012-01-17 21:48:47 +02003269 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3270 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3271 conn->dst_type, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003272
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003273 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003274 conn->handle = __le16_to_cpu(ev->handle);
3275 conn->state = BT_CONNECTED;
3276
3277 hci_conn_hold_device(conn);
3278 hci_conn_add_sysfs(conn);
3279
3280 hci_proto_connect_cfm(conn, ev->status);
3281
3282unlock:
3283 hci_dev_unlock(hdev);
3284}
3285
Andre Guedes9aa04c92011-05-26 16:23:51 -03003286static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3287 struct sk_buff *skb)
3288{
Andre Guedese95beb42011-09-26 20:48:35 -03003289 u8 num_reports = skb->data[0];
3290 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003291 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003292
3293 hci_dev_lock(hdev);
3294
Andre Guedese95beb42011-09-26 20:48:35 -03003295 while (num_reports--) {
3296 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003297
Andre Guedes9aa04c92011-05-26 16:23:51 -03003298 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003299
Andre Guedes3c9e9192012-01-10 18:20:50 -03003300 rssi = ev->data[ev->length];
3301 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3302 NULL, rssi, 0, ev->data, ev->length);
3303
Andre Guedese95beb42011-09-26 20:48:35 -03003304 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003305 }
3306
3307 hci_dev_unlock(hdev);
3308}
3309
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003310static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3311 struct sk_buff *skb)
3312{
3313 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3314 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003315 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003316 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003317 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003318
3319 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3320
3321 hci_dev_lock(hdev);
3322
3323 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003324 if (conn == NULL)
3325 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003326
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003327 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3328 if (ltk == NULL)
3329 goto not_found;
3330
3331 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003332 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003333
3334 if (ltk->authenticated)
3335 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003336
3337 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3338
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003339 if (ltk->type & HCI_SMP_STK) {
3340 list_del(&ltk->list);
3341 kfree(ltk);
3342 }
3343
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003344 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003345
3346 return;
3347
3348not_found:
3349 neg.handle = ev->handle;
3350 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3351 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003352}
3353
Ville Tervofcd89c02011-02-10 22:38:47 -03003354static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3355{
3356 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3357
3358 skb_pull(skb, sizeof(*le_ev));
3359
3360 switch (le_ev->subevent) {
3361 case HCI_EV_LE_CONN_COMPLETE:
3362 hci_le_conn_complete_evt(hdev, skb);
3363 break;
3364
Andre Guedes9aa04c92011-05-26 16:23:51 -03003365 case HCI_EV_LE_ADVERTISING_REPORT:
3366 hci_le_adv_report_evt(hdev, skb);
3367 break;
3368
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003369 case HCI_EV_LE_LTK_REQ:
3370 hci_le_ltk_request_evt(hdev, skb);
3371 break;
3372
Ville Tervofcd89c02011-02-10 22:38:47 -03003373 default:
3374 break;
3375 }
3376}
3377
Linus Torvalds1da177e2005-04-16 15:20:36 -07003378void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3379{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003380 struct hci_event_hdr *hdr = (void *) skb->data;
3381 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003382
3383 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3384
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003385 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003386 case HCI_EV_INQUIRY_COMPLETE:
3387 hci_inquiry_complete_evt(hdev, skb);
3388 break;
3389
3390 case HCI_EV_INQUIRY_RESULT:
3391 hci_inquiry_result_evt(hdev, skb);
3392 break;
3393
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003394 case HCI_EV_CONN_COMPLETE:
3395 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003396 break;
3397
Linus Torvalds1da177e2005-04-16 15:20:36 -07003398 case HCI_EV_CONN_REQUEST:
3399 hci_conn_request_evt(hdev, skb);
3400 break;
3401
Linus Torvalds1da177e2005-04-16 15:20:36 -07003402 case HCI_EV_DISCONN_COMPLETE:
3403 hci_disconn_complete_evt(hdev, skb);
3404 break;
3405
Linus Torvalds1da177e2005-04-16 15:20:36 -07003406 case HCI_EV_AUTH_COMPLETE:
3407 hci_auth_complete_evt(hdev, skb);
3408 break;
3409
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003410 case HCI_EV_REMOTE_NAME:
3411 hci_remote_name_evt(hdev, skb);
3412 break;
3413
Linus Torvalds1da177e2005-04-16 15:20:36 -07003414 case HCI_EV_ENCRYPT_CHANGE:
3415 hci_encrypt_change_evt(hdev, skb);
3416 break;
3417
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003418 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3419 hci_change_link_key_complete_evt(hdev, skb);
3420 break;
3421
3422 case HCI_EV_REMOTE_FEATURES:
3423 hci_remote_features_evt(hdev, skb);
3424 break;
3425
3426 case HCI_EV_REMOTE_VERSION:
3427 hci_remote_version_evt(hdev, skb);
3428 break;
3429
3430 case HCI_EV_QOS_SETUP_COMPLETE:
3431 hci_qos_setup_complete_evt(hdev, skb);
3432 break;
3433
3434 case HCI_EV_CMD_COMPLETE:
3435 hci_cmd_complete_evt(hdev, skb);
3436 break;
3437
3438 case HCI_EV_CMD_STATUS:
3439 hci_cmd_status_evt(hdev, skb);
3440 break;
3441
3442 case HCI_EV_ROLE_CHANGE:
3443 hci_role_change_evt(hdev, skb);
3444 break;
3445
3446 case HCI_EV_NUM_COMP_PKTS:
3447 hci_num_comp_pkts_evt(hdev, skb);
3448 break;
3449
3450 case HCI_EV_MODE_CHANGE:
3451 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003452 break;
3453
3454 case HCI_EV_PIN_CODE_REQ:
3455 hci_pin_code_request_evt(hdev, skb);
3456 break;
3457
3458 case HCI_EV_LINK_KEY_REQ:
3459 hci_link_key_request_evt(hdev, skb);
3460 break;
3461
3462 case HCI_EV_LINK_KEY_NOTIFY:
3463 hci_link_key_notify_evt(hdev, skb);
3464 break;
3465
3466 case HCI_EV_CLOCK_OFFSET:
3467 hci_clock_offset_evt(hdev, skb);
3468 break;
3469
Marcel Holtmanna8746412008-07-14 20:13:46 +02003470 case HCI_EV_PKT_TYPE_CHANGE:
3471 hci_pkt_type_change_evt(hdev, skb);
3472 break;
3473
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003474 case HCI_EV_PSCAN_REP_MODE:
3475 hci_pscan_rep_mode_evt(hdev, skb);
3476 break;
3477
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003478 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3479 hci_inquiry_result_with_rssi_evt(hdev, skb);
3480 break;
3481
3482 case HCI_EV_REMOTE_EXT_FEATURES:
3483 hci_remote_ext_features_evt(hdev, skb);
3484 break;
3485
3486 case HCI_EV_SYNC_CONN_COMPLETE:
3487 hci_sync_conn_complete_evt(hdev, skb);
3488 break;
3489
3490 case HCI_EV_SYNC_CONN_CHANGED:
3491 hci_sync_conn_changed_evt(hdev, skb);
3492 break;
3493
Marcel Holtmann04837f62006-07-03 10:02:33 +02003494 case HCI_EV_SNIFF_SUBRATE:
3495 hci_sniff_subrate_evt(hdev, skb);
3496 break;
3497
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003498 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3499 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003500 break;
3501
Marcel Holtmann04936842008-07-14 20:13:48 +02003502 case HCI_EV_IO_CAPA_REQUEST:
3503 hci_io_capa_request_evt(hdev, skb);
3504 break;
3505
Johan Hedberg03b555e2011-01-04 15:40:05 +02003506 case HCI_EV_IO_CAPA_REPLY:
3507 hci_io_capa_reply_evt(hdev, skb);
3508 break;
3509
Johan Hedberga5c29682011-02-19 12:05:57 -03003510 case HCI_EV_USER_CONFIRM_REQUEST:
3511 hci_user_confirm_request_evt(hdev, skb);
3512 break;
3513
Brian Gix1143d452011-11-23 08:28:34 -08003514 case HCI_EV_USER_PASSKEY_REQUEST:
3515 hci_user_passkey_request_evt(hdev, skb);
3516 break;
3517
Marcel Holtmann04936842008-07-14 20:13:48 +02003518 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3519 hci_simple_pair_complete_evt(hdev, skb);
3520 break;
3521
Marcel Holtmann41a96212008-07-14 20:13:48 +02003522 case HCI_EV_REMOTE_HOST_FEATURES:
3523 hci_remote_host_features_evt(hdev, skb);
3524 break;
3525
Ville Tervofcd89c02011-02-10 22:38:47 -03003526 case HCI_EV_LE_META:
3527 hci_le_meta_evt(hdev, skb);
3528 break;
3529
Szymon Janc2763eda2011-03-22 13:12:22 +01003530 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3531 hci_remote_oob_data_request_evt(hdev, skb);
3532 break;
3533
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003534 case HCI_EV_NUM_COMP_BLOCKS:
3535 hci_num_comp_blocks_evt(hdev, skb);
3536 break;
3537
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003538 default:
3539 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003540 break;
3541 }
3542
3543 kfree_skb(skb);
3544 hdev->stat.evt_rx++;
3545}