blob: 9917fe3d1d18e7d11c7e41879cf2df55ee687b8d [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <net/sock.h>
39
40#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020041#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <asm/unaligned.h>
43
44#include <net/bluetooth/bluetooth.h>
45#include <net/bluetooth/hci_core.h>
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047/* Handle HCI Event packets */
48
Marcel Holtmanna9de9242007-10-20 13:33:56 +020049static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070050{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020051 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
Marcel Holtmanna9de9242007-10-20 13:33:56 +020053 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Andre Guedese6d465c2011-11-09 17:14:26 -030055 if (status) {
56 hci_dev_lock(hdev);
57 mgmt_stop_discovery_failed(hdev, status);
58 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020059 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030060 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
Andre Guedes89352e72011-11-04 14:16:53 -030062 clear_bit(HCI_INQUIRY, &hdev->flags);
63
Johan Hedberg56e5cb82011-11-08 20:40:16 +020064 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020065 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020066 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010067
Johan Hedberg23bb5762010-12-21 23:01:27 +020068 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010069
Marcel Holtmanna9de9242007-10-20 13:33:56 +020070 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070071}
72
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020075 __u8 status = *((__u8 *) skb->data);
76
77 BT_DBG("%s status 0x%x", hdev->name, status);
78
79 if (status)
80 return;
81
Marcel Holtmanna9de9242007-10-20 13:33:56 +020082 hci_conn_check_pending(hdev);
83}
84
85static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
86{
87 BT_DBG("%s", hdev->name);
88}
89
90static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
91{
92 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 if (rp->status)
98 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200102 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
103 if (conn) {
104 if (rp->role)
105 conn->link_mode &= ~HCI_LM_MASTER;
106 else
107 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200109
110 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111}
112
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200113static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
114{
115 struct hci_rp_read_link_policy *rp = (void *) skb->data;
116 struct hci_conn *conn;
117
118 BT_DBG("%s status 0x%x", hdev->name, rp->status);
119
120 if (rp->status)
121 return;
122
123 hci_dev_lock(hdev);
124
125 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
126 if (conn)
127 conn->link_policy = __le16_to_cpu(rp->policy);
128
129 hci_dev_unlock(hdev);
130}
131
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200132static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200134 struct hci_rp_write_link_policy *rp = (void *) skb->data;
135 struct hci_conn *conn;
136 void *sent;
137
138 BT_DBG("%s status 0x%x", hdev->name, rp->status);
139
140 if (rp->status)
141 return;
142
143 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
144 if (!sent)
145 return;
146
147 hci_dev_lock(hdev);
148
149 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200150 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700151 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200152
153 hci_dev_unlock(hdev);
154}
155
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200156static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
157{
158 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
159
160 BT_DBG("%s status 0x%x", hdev->name, rp->status);
161
162 if (rp->status)
163 return;
164
165 hdev->link_policy = __le16_to_cpu(rp->policy);
166}
167
168static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
169{
170 __u8 status = *((__u8 *) skb->data);
171 void *sent;
172
173 BT_DBG("%s status 0x%x", hdev->name, status);
174
175 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
176 if (!sent)
177 return;
178
179 if (!status)
180 hdev->link_policy = get_unaligned_le16(sent);
181
Johan Hedberg23bb5762010-12-21 23:01:27 +0200182 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200183}
184
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200185static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
186{
187 __u8 status = *((__u8 *) skb->data);
188
189 BT_DBG("%s status 0x%x", hdev->name, status);
190
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300191 clear_bit(HCI_RESET, &hdev->flags);
192
Johan Hedberg23bb5762010-12-21 23:01:27 +0200193 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300194
Johan Hedberga297e972012-02-21 17:55:47 +0200195 /* Reset all non-persistent flags */
196 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200197}
198
199static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
200{
201 __u8 status = *((__u8 *) skb->data);
202 void *sent;
203
204 BT_DBG("%s status 0x%x", hdev->name, status);
205
206 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
207 if (!sent)
208 return;
209
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200210 hci_dev_lock(hdev);
211
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200212 if (status == 0)
213 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200214
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200215 if (test_bit(HCI_MGMT, &hdev->dev_flags))
216 mgmt_set_local_name_complete(hdev, sent, status);
217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200219}
220
221static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
222{
223 struct hci_rp_read_local_name *rp = (void *) skb->data;
224
225 BT_DBG("%s status 0x%x", hdev->name, rp->status);
226
227 if (rp->status)
228 return;
229
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200230 if (test_bit(HCI_SETUP, &hdev->dev_flags))
231 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
354 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
355 if (!sent)
356 return;
357
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100358 hci_dev_lock(hdev);
359
360 if (status == 0)
361 memcpy(hdev->dev_class, sent, 3);
362
363 if (test_bit(HCI_MGMT, &hdev->dev_flags))
364 mgmt_set_class_of_dev_complete(hdev, sent, status);
365
366 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200367}
368
369static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
370{
371 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200373
374 BT_DBG("%s status 0x%x", hdev->name, rp->status);
375
376 if (rp->status)
377 return;
378
379 setting = __le16_to_cpu(rp->voice_setting);
380
Marcel Holtmannf383f272008-07-14 20:13:47 +0200381 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200382 return;
383
384 hdev->voice_setting = setting;
385
386 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
387
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200388 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200390}
391
392static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
393{
394 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200395 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 void *sent;
397
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200398 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399
Marcel Holtmannf383f272008-07-14 20:13:47 +0200400 if (status)
401 return;
402
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200403 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
404 if (!sent)
405 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
Marcel Holtmannf383f272008-07-14 20:13:47 +0200407 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Marcel Holtmannf383f272008-07-14 20:13:47 +0200409 if (hdev->voice_setting == setting)
410 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Marcel Holtmannf383f272008-07-14 20:13:47 +0200412 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413
Marcel Holtmannf383f272008-07-14 20:13:47 +0200414 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
415
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200416 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200417 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418}
419
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200420static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200422 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200424 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
Johan Hedberg23bb5762010-12-21 23:01:27 +0200426 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427}
428
Marcel Holtmann333140b2008-07-14 20:13:48 +0200429static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
430{
431 __u8 status = *((__u8 *) skb->data);
432 void *sent;
433
434 BT_DBG("%s status 0x%x", hdev->name, status);
435
Marcel Holtmann333140b2008-07-14 20:13:48 +0200436 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
437 if (!sent)
438 return;
439
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200440 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200441 mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status);
442 else if (!status) {
443 if (*((u8 *) sent))
444 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
445 else
446 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
447 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200448}
449
Johan Hedbergd5859e22011-01-25 01:19:58 +0200450static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
451{
452 if (hdev->features[6] & LMP_EXT_INQ)
453 return 2;
454
455 if (hdev->features[3] & LMP_RSSI_INQ)
456 return 1;
457
458 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
459 hdev->lmp_subver == 0x0757)
460 return 1;
461
462 if (hdev->manufacturer == 15) {
463 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
464 return 1;
465 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
466 return 1;
467 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
468 return 1;
469 }
470
471 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
472 hdev->lmp_subver == 0x1805)
473 return 1;
474
475 return 0;
476}
477
478static void hci_setup_inquiry_mode(struct hci_dev *hdev)
479{
480 u8 mode;
481
482 mode = hci_get_inquiry_mode(hdev);
483
484 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
485}
486
487static void hci_setup_event_mask(struct hci_dev *hdev)
488{
489 /* The second byte is 0xff instead of 0x9f (two reserved bits
490 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
491 * command otherwise */
492 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
493
Ville Tervo6de6c182011-05-27 11:16:21 +0300494 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
495 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200496 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300497 return;
498
499 events[4] |= 0x01; /* Flow Specification Complete */
500 events[4] |= 0x02; /* Inquiry Result with RSSI */
501 events[4] |= 0x04; /* Read Remote Extended Features Complete */
502 events[5] |= 0x08; /* Synchronous Connection Complete */
503 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200504
505 if (hdev->features[3] & LMP_RSSI_INQ)
506 events[4] |= 0x04; /* Inquiry Result with RSSI */
507
508 if (hdev->features[5] & LMP_SNIFF_SUBR)
509 events[5] |= 0x20; /* Sniff Subrating */
510
511 if (hdev->features[5] & LMP_PAUSE_ENC)
512 events[5] |= 0x80; /* Encryption Key Refresh Complete */
513
514 if (hdev->features[6] & LMP_EXT_INQ)
515 events[5] |= 0x40; /* Extended Inquiry Result */
516
517 if (hdev->features[6] & LMP_NO_FLUSH)
518 events[7] |= 0x01; /* Enhanced Flush Complete */
519
520 if (hdev->features[7] & LMP_LSTO)
521 events[6] |= 0x80; /* Link Supervision Timeout Changed */
522
523 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
524 events[6] |= 0x01; /* IO Capability Request */
525 events[6] |= 0x02; /* IO Capability Response */
526 events[6] |= 0x04; /* User Confirmation Request */
527 events[6] |= 0x08; /* User Passkey Request */
528 events[6] |= 0x10; /* Remote OOB Data Request */
529 events[6] |= 0x20; /* Simple Pairing Complete */
530 events[7] |= 0x04; /* User Passkey Notification */
531 events[7] |= 0x08; /* Keypress Notification */
532 events[7] |= 0x10; /* Remote Host Supported
533 * Features Notification */
534 }
535
536 if (hdev->features[4] & LMP_LE)
537 events[7] |= 0x20; /* LE Meta-Event */
538
539 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
540}
541
Andre Guedese6100a22011-06-30 19:20:54 -0300542static void hci_set_le_support(struct hci_dev *hdev)
543{
544 struct hci_cp_write_le_host_supported cp;
545
546 memset(&cp, 0, sizeof(cp));
547
Johan Hedberg06199cf2012-02-22 16:37:11 +0200548 if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
Andre Guedese6100a22011-06-30 19:20:54 -0300549 cp.le = 1;
550 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
551 }
552
553 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
554}
555
Johan Hedbergd5859e22011-01-25 01:19:58 +0200556static void hci_setup(struct hci_dev *hdev)
557{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200558 if (hdev->dev_type != HCI_BREDR)
559 return;
560
Johan Hedbergd5859e22011-01-25 01:19:58 +0200561 hci_setup_event_mask(hdev);
562
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200563 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200564 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
565
Johan Hedberg54d04db2012-02-22 15:47:48 +0200566 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
567 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
568 u8 mode = 0x01;
569 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
570 sizeof(mode), &mode);
571 } else {
572 struct hci_cp_write_eir cp;
573
574 memset(hdev->eir, 0, sizeof(hdev->eir));
575 memset(&cp, 0, sizeof(cp));
576
577 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
578 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200579 }
580
581 if (hdev->features[3] & LMP_RSSI_INQ)
582 hci_setup_inquiry_mode(hdev);
583
584 if (hdev->features[7] & LMP_INQ_TX_PWR)
585 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300586
587 if (hdev->features[7] & LMP_EXTFEATURES) {
588 struct hci_cp_read_local_ext_features cp;
589
590 cp.page = 0x01;
591 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
592 sizeof(cp), &cp);
593 }
Andre Guedese6100a22011-06-30 19:20:54 -0300594
Johan Hedberg47990ea2012-02-22 11:58:37 +0200595 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
596 u8 enable = 1;
597 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE,
598 sizeof(enable), &enable);
599 }
600
Andre Guedese6100a22011-06-30 19:20:54 -0300601 if (hdev->features[4] & LMP_LE)
602 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200603}
604
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200605static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
606{
607 struct hci_rp_read_local_version *rp = (void *) skb->data;
608
609 BT_DBG("%s status 0x%x", hdev->name, rp->status);
610
611 if (rp->status)
612 return;
613
614 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200615 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200616 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200617 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200618 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200619
620 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
621 hdev->manufacturer,
622 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200623
624 if (test_bit(HCI_INIT, &hdev->flags))
625 hci_setup(hdev);
626}
627
628static void hci_setup_link_policy(struct hci_dev *hdev)
629{
630 u16 link_policy = 0;
631
632 if (hdev->features[0] & LMP_RSWITCH)
633 link_policy |= HCI_LP_RSWITCH;
634 if (hdev->features[0] & LMP_HOLD)
635 link_policy |= HCI_LP_HOLD;
636 if (hdev->features[0] & LMP_SNIFF)
637 link_policy |= HCI_LP_SNIFF;
638 if (hdev->features[1] & LMP_PARK)
639 link_policy |= HCI_LP_PARK;
640
641 link_policy = cpu_to_le16(link_policy);
642 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
643 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200644}
645
646static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
647{
648 struct hci_rp_read_local_commands *rp = (void *) skb->data;
649
650 BT_DBG("%s status 0x%x", hdev->name, rp->status);
651
652 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200653 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200654
655 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200656
657 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
658 hci_setup_link_policy(hdev);
659
660done:
661 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200662}
663
664static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
665{
666 struct hci_rp_read_local_features *rp = (void *) skb->data;
667
668 BT_DBG("%s status 0x%x", hdev->name, rp->status);
669
670 if (rp->status)
671 return;
672
673 memcpy(hdev->features, rp->features, 8);
674
675 /* Adjust default settings according to features
676 * supported by device. */
677
678 if (hdev->features[0] & LMP_3SLOT)
679 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
680
681 if (hdev->features[0] & LMP_5SLOT)
682 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
683
684 if (hdev->features[1] & LMP_HV2) {
685 hdev->pkt_type |= (HCI_HV2);
686 hdev->esco_type |= (ESCO_HV2);
687 }
688
689 if (hdev->features[1] & LMP_HV3) {
690 hdev->pkt_type |= (HCI_HV3);
691 hdev->esco_type |= (ESCO_HV3);
692 }
693
694 if (hdev->features[3] & LMP_ESCO)
695 hdev->esco_type |= (ESCO_EV3);
696
697 if (hdev->features[4] & LMP_EV4)
698 hdev->esco_type |= (ESCO_EV4);
699
700 if (hdev->features[4] & LMP_EV5)
701 hdev->esco_type |= (ESCO_EV5);
702
Marcel Holtmannefc76882009-02-06 09:13:37 +0100703 if (hdev->features[5] & LMP_EDR_ESCO_2M)
704 hdev->esco_type |= (ESCO_2EV3);
705
706 if (hdev->features[5] & LMP_EDR_ESCO_3M)
707 hdev->esco_type |= (ESCO_3EV3);
708
709 if (hdev->features[5] & LMP_EDR_3S_ESCO)
710 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
711
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200712 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
713 hdev->features[0], hdev->features[1],
714 hdev->features[2], hdev->features[3],
715 hdev->features[4], hdev->features[5],
716 hdev->features[6], hdev->features[7]);
717}
718
Andre Guedes971e3a42011-06-30 19:20:52 -0300719static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
720 struct sk_buff *skb)
721{
722 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
723
724 BT_DBG("%s status 0x%x", hdev->name, rp->status);
725
726 if (rp->status)
727 return;
728
Andre Guedesb5b32b62011-12-30 10:34:04 -0300729 switch (rp->page) {
730 case 0:
731 memcpy(hdev->features, rp->features, 8);
732 break;
733 case 1:
734 memcpy(hdev->host_features, rp->features, 8);
735 break;
736 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300737
738 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
739}
740
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200741static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
742 struct sk_buff *skb)
743{
744 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
745
746 BT_DBG("%s status 0x%x", hdev->name, rp->status);
747
748 if (rp->status)
749 return;
750
751 hdev->flow_ctl_mode = rp->mode;
752
753 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
754}
755
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200756static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
757{
758 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
759
760 BT_DBG("%s status 0x%x", hdev->name, rp->status);
761
762 if (rp->status)
763 return;
764
765 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
766 hdev->sco_mtu = rp->sco_mtu;
767 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
768 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
769
770 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
771 hdev->sco_mtu = 64;
772 hdev->sco_pkts = 8;
773 }
774
775 hdev->acl_cnt = hdev->acl_pkts;
776 hdev->sco_cnt = hdev->sco_pkts;
777
778 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
779 hdev->acl_mtu, hdev->acl_pkts,
780 hdev->sco_mtu, hdev->sco_pkts);
781}
782
783static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
784{
785 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
786
787 BT_DBG("%s status 0x%x", hdev->name, rp->status);
788
789 if (!rp->status)
790 bacpy(&hdev->bdaddr, &rp->bdaddr);
791
Johan Hedberg23bb5762010-12-21 23:01:27 +0200792 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
793}
794
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200795static void hci_cc_read_data_block_size(struct hci_dev *hdev,
796 struct sk_buff *skb)
797{
798 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
799
800 BT_DBG("%s status 0x%x", hdev->name, rp->status);
801
802 if (rp->status)
803 return;
804
805 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
806 hdev->block_len = __le16_to_cpu(rp->block_len);
807 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
808
809 hdev->block_cnt = hdev->num_blocks;
810
811 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
812 hdev->block_cnt, hdev->block_len);
813
814 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
815}
816
Johan Hedberg23bb5762010-12-21 23:01:27 +0200817static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
818{
819 __u8 status = *((__u8 *) skb->data);
820
821 BT_DBG("%s status 0x%x", hdev->name, status);
822
823 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200824}
825
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300826static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
827 struct sk_buff *skb)
828{
829 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
830
831 BT_DBG("%s status 0x%x", hdev->name, rp->status);
832
833 if (rp->status)
834 return;
835
836 hdev->amp_status = rp->amp_status;
837 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
838 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
839 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
840 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
841 hdev->amp_type = rp->amp_type;
842 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
843 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
844 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
845 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
846
847 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
848}
849
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200850static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
851 struct sk_buff *skb)
852{
853 __u8 status = *((__u8 *) skb->data);
854
855 BT_DBG("%s status 0x%x", hdev->name, status);
856
857 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
858}
859
Johan Hedbergd5859e22011-01-25 01:19:58 +0200860static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
861{
862 __u8 status = *((__u8 *) skb->data);
863
864 BT_DBG("%s status 0x%x", hdev->name, status);
865
866 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
867}
868
869static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
870 struct sk_buff *skb)
871{
872 __u8 status = *((__u8 *) skb->data);
873
874 BT_DBG("%s status 0x%x", hdev->name, status);
875
876 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
877}
878
879static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
880 struct sk_buff *skb)
881{
882 __u8 status = *((__u8 *) skb->data);
883
884 BT_DBG("%s status 0x%x", hdev->name, status);
885
886 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
887}
888
889static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
890{
891 __u8 status = *((__u8 *) skb->data);
892
893 BT_DBG("%s status 0x%x", hdev->name, status);
894
895 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
896}
897
Johan Hedberg980e1a52011-01-22 06:10:07 +0200898static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
899{
900 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
901 struct hci_cp_pin_code_reply *cp;
902 struct hci_conn *conn;
903
904 BT_DBG("%s status 0x%x", hdev->name, rp->status);
905
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200906 hci_dev_lock(hdev);
907
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200908 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200909 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200910
911 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200912 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200913
914 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
915 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200916 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200917
918 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
919 if (conn)
920 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200921
922unlock:
923 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200924}
925
926static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
927{
928 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
929
930 BT_DBG("%s status 0x%x", hdev->name, rp->status);
931
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200932 hci_dev_lock(hdev);
933
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200934 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200935 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200936 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200937
938 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200939}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200940
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300941static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
942 struct sk_buff *skb)
943{
944 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
945
946 BT_DBG("%s status 0x%x", hdev->name, rp->status);
947
948 if (rp->status)
949 return;
950
951 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
952 hdev->le_pkts = rp->le_max_pkt;
953
954 hdev->le_cnt = hdev->le_pkts;
955
956 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
957
958 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
959}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200960
Johan Hedberga5c29682011-02-19 12:05:57 -0300961static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
962{
963 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
964
965 BT_DBG("%s status 0x%x", hdev->name, rp->status);
966
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200967 hci_dev_lock(hdev);
968
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200969 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200970 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
971 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200972
973 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300974}
975
976static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
977 struct sk_buff *skb)
978{
979 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
980
981 BT_DBG("%s status 0x%x", hdev->name, rp->status);
982
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200983 hci_dev_lock(hdev);
984
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200985 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200986 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200987 ACL_LINK, 0,
Johan Hedberga5c29682011-02-19 12:05:57 -0300988 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200989
990 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300991}
992
Brian Gix1143d452011-11-23 08:28:34 -0800993static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
994{
995 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
996
997 BT_DBG("%s status 0x%x", hdev->name, rp->status);
998
999 hci_dev_lock(hdev);
1000
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001001 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001002 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1003 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001004
1005 hci_dev_unlock(hdev);
1006}
1007
1008static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1009 struct sk_buff *skb)
1010{
1011 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1012
1013 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1014
1015 hci_dev_lock(hdev);
1016
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001017 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001018 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001019 ACL_LINK, 0,
Brian Gix1143d452011-11-23 08:28:34 -08001020 rp->status);
1021
1022 hci_dev_unlock(hdev);
1023}
1024
Szymon Jancc35938b2011-03-22 13:12:21 +01001025static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1026 struct sk_buff *skb)
1027{
1028 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1029
1030 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1031
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001032 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001033 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001034 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001035 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001036}
1037
Andre Guedes07f7fa52011-12-02 21:13:31 +09001038static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1039{
1040 __u8 status = *((__u8 *) skb->data);
1041
1042 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001043
1044 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001045
1046 if (status) {
1047 hci_dev_lock(hdev);
1048 mgmt_start_discovery_failed(hdev, status);
1049 hci_dev_unlock(hdev);
1050 return;
1051 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001052}
1053
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001054static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1055 struct sk_buff *skb)
1056{
1057 struct hci_cp_le_set_scan_enable *cp;
1058 __u8 status = *((__u8 *) skb->data);
1059
1060 BT_DBG("%s status 0x%x", hdev->name, status);
1061
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001062 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1063 if (!cp)
1064 return;
1065
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001066 switch (cp->enable) {
1067 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001068 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1069
Andre Guedes3fd24152012-02-03 17:48:01 -03001070 if (status) {
1071 hci_dev_lock(hdev);
1072 mgmt_start_discovery_failed(hdev, status);
1073 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001074 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001075 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001076
Andre Guedesd23264a2011-11-25 20:53:38 -03001077 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1078
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001079 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001080
1081 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001082 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001083 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001084 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001085 break;
1086
1087 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001088 if (status)
1089 return;
1090
Andre Guedesd23264a2011-11-25 20:53:38 -03001091 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1092
Andre Guedesd0843292012-01-02 19:18:11 -03001093 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001094
1095 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1096 mgmt_interleaved_discovery(hdev);
1097 } else {
1098 hci_dev_lock(hdev);
1099 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1100 hci_dev_unlock(hdev);
1101 }
1102
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001103 break;
1104
1105 default:
1106 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1107 break;
Andre Guedes35815082011-05-26 16:23:53 -03001108 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001109}
1110
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001111static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1112{
1113 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1114
1115 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1116
1117 if (rp->status)
1118 return;
1119
1120 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1121}
1122
1123static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1124{
1125 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1126
1127 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1128
1129 if (rp->status)
1130 return;
1131
1132 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1133}
1134
Andre Guedesf9b49302011-06-30 19:20:53 -03001135static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1136 struct sk_buff *skb)
1137{
1138 struct hci_cp_read_local_ext_features cp;
Johan Hedberg06199cf2012-02-22 16:37:11 +02001139 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001140 __u8 status = *((__u8 *) skb->data);
1141
1142 BT_DBG("%s status 0x%x", hdev->name, status);
1143
Johan Hedberg06199cf2012-02-22 16:37:11 +02001144 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
1145 if (sent && test_bit(HCI_MGMT, &hdev->dev_flags))
1146 mgmt_le_enable_complete(hdev, sent->le, status);
1147
Andre Guedesf9b49302011-06-30 19:20:53 -03001148 if (status)
1149 return;
1150
1151 cp.page = 0x01;
1152 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1153}
1154
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001155static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1156{
1157 BT_DBG("%s status 0x%x", hdev->name, status);
1158
1159 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001160 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001161 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001162 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001163 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001164 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001165 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001166 return;
1167 }
1168
Andre Guedes89352e72011-11-04 14:16:53 -03001169 set_bit(HCI_INQUIRY, &hdev->flags);
1170
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001171 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001172 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001173 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001174}
1175
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1177{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001178 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001181 BT_DBG("%s status 0x%x", hdev->name, status);
1182
1183 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184 if (!cp)
1185 return;
1186
1187 hci_dev_lock(hdev);
1188
1189 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1190
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001191 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192
1193 if (status) {
1194 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001195 if (status != 0x0c || conn->attempt > 2) {
1196 conn->state = BT_CLOSED;
1197 hci_proto_connect_cfm(conn, status);
1198 hci_conn_del(conn);
1199 } else
1200 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201 }
1202 } else {
1203 if (!conn) {
1204 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1205 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001206 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 conn->link_mode |= HCI_LM_MASTER;
1208 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001209 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 }
1211 }
1212
1213 hci_dev_unlock(hdev);
1214}
1215
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001216static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001218 struct hci_cp_add_sco *cp;
1219 struct hci_conn *acl, *sco;
1220 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001222 BT_DBG("%s status 0x%x", hdev->name, status);
1223
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001224 if (!status)
1225 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001227 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1228 if (!cp)
1229 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001231 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001233 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001234
1235 hci_dev_lock(hdev);
1236
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001237 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001238 if (acl) {
1239 sco = acl->link;
1240 if (sco) {
1241 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001242
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001243 hci_proto_connect_cfm(sco, status);
1244 hci_conn_del(sco);
1245 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001246 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001247
1248 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249}
1250
Marcel Holtmannf8558552008-07-14 20:13:49 +02001251static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1252{
1253 struct hci_cp_auth_requested *cp;
1254 struct hci_conn *conn;
1255
1256 BT_DBG("%s status 0x%x", hdev->name, status);
1257
1258 if (!status)
1259 return;
1260
1261 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1262 if (!cp)
1263 return;
1264
1265 hci_dev_lock(hdev);
1266
1267 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1268 if (conn) {
1269 if (conn->state == BT_CONFIG) {
1270 hci_proto_connect_cfm(conn, status);
1271 hci_conn_put(conn);
1272 }
1273 }
1274
1275 hci_dev_unlock(hdev);
1276}
1277
1278static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1279{
1280 struct hci_cp_set_conn_encrypt *cp;
1281 struct hci_conn *conn;
1282
1283 BT_DBG("%s status 0x%x", hdev->name, status);
1284
1285 if (!status)
1286 return;
1287
1288 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1289 if (!cp)
1290 return;
1291
1292 hci_dev_lock(hdev);
1293
1294 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1295 if (conn) {
1296 if (conn->state == BT_CONFIG) {
1297 hci_proto_connect_cfm(conn, status);
1298 hci_conn_put(conn);
1299 }
1300 }
1301
1302 hci_dev_unlock(hdev);
1303}
1304
Johan Hedberg127178d2010-11-18 22:22:29 +02001305static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001306 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001307{
Johan Hedberg392599b2010-11-18 22:22:28 +02001308 if (conn->state != BT_CONFIG || !conn->out)
1309 return 0;
1310
Johan Hedberg765c2a92011-01-19 12:06:52 +05301311 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001312 return 0;
1313
1314 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001315 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001316 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001317 conn->pending_sec_level != BT_SECURITY_HIGH &&
1318 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001319 return 0;
1320
Johan Hedberg392599b2010-11-18 22:22:28 +02001321 return 1;
1322}
1323
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001324static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1325{
1326 struct hci_cp_remote_name_req cp;
1327
1328 memset(&cp, 0, sizeof(cp));
1329
1330 bacpy(&cp.bdaddr, &e->data.bdaddr);
1331 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1332 cp.pscan_mode = e->data.pscan_mode;
1333 cp.clock_offset = e->data.clock_offset;
1334
1335 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1336}
1337
Johan Hedbergb644ba32012-01-17 21:48:47 +02001338static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001339{
1340 struct discovery_state *discov = &hdev->discovery;
1341 struct inquiry_entry *e;
1342
Johan Hedbergb644ba32012-01-17 21:48:47 +02001343 if (list_empty(&discov->resolve))
1344 return false;
1345
1346 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1347 if (hci_resolve_name(hdev, e) == 0) {
1348 e->name_state = NAME_PENDING;
1349 return true;
1350 }
1351
1352 return false;
1353}
1354
1355static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1356 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1357{
1358 struct discovery_state *discov = &hdev->discovery;
1359 struct inquiry_entry *e;
1360
1361 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1362 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
1363 name, name_len, conn->dev_class);
1364
1365 if (discov->state == DISCOVERY_STOPPED)
1366 return;
1367
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001368 if (discov->state == DISCOVERY_STOPPING)
1369 goto discov_complete;
1370
1371 if (discov->state != DISCOVERY_RESOLVING)
1372 return;
1373
1374 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1375 if (e) {
1376 e->name_state = NAME_KNOWN;
1377 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001378 if (name)
1379 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1380 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001381 }
1382
Johan Hedbergb644ba32012-01-17 21:48:47 +02001383 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001384 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001385
1386discov_complete:
1387 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1388}
1389
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001390static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1391{
Johan Hedberg127178d2010-11-18 22:22:29 +02001392 struct hci_cp_remote_name_req *cp;
1393 struct hci_conn *conn;
1394
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001395 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001396
1397 /* If successful wait for the name req complete event before
1398 * checking for the need to do authentication */
1399 if (!status)
1400 return;
1401
1402 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1403 if (!cp)
1404 return;
1405
1406 hci_dev_lock(hdev);
1407
1408 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001409
1410 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1411 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1412
Johan Hedberg79c6c702011-04-28 11:28:55 -07001413 if (!conn)
1414 goto unlock;
1415
1416 if (!hci_outgoing_auth_needed(hdev, conn))
1417 goto unlock;
1418
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001419 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001420 struct hci_cp_auth_requested cp;
1421 cp.handle = __cpu_to_le16(conn->handle);
1422 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1423 }
1424
Johan Hedberg79c6c702011-04-28 11:28:55 -07001425unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001426 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001427}
1428
Marcel Holtmann769be972008-07-14 20:13:49 +02001429static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1430{
1431 struct hci_cp_read_remote_features *cp;
1432 struct hci_conn *conn;
1433
1434 BT_DBG("%s status 0x%x", hdev->name, status);
1435
1436 if (!status)
1437 return;
1438
1439 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1440 if (!cp)
1441 return;
1442
1443 hci_dev_lock(hdev);
1444
1445 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1446 if (conn) {
1447 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001448 hci_proto_connect_cfm(conn, status);
1449 hci_conn_put(conn);
1450 }
1451 }
1452
1453 hci_dev_unlock(hdev);
1454}
1455
1456static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1457{
1458 struct hci_cp_read_remote_ext_features *cp;
1459 struct hci_conn *conn;
1460
1461 BT_DBG("%s status 0x%x", hdev->name, status);
1462
1463 if (!status)
1464 return;
1465
1466 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1467 if (!cp)
1468 return;
1469
1470 hci_dev_lock(hdev);
1471
1472 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1473 if (conn) {
1474 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001475 hci_proto_connect_cfm(conn, status);
1476 hci_conn_put(conn);
1477 }
1478 }
1479
1480 hci_dev_unlock(hdev);
1481}
1482
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001483static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1484{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001485 struct hci_cp_setup_sync_conn *cp;
1486 struct hci_conn *acl, *sco;
1487 __u16 handle;
1488
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001489 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001490
1491 if (!status)
1492 return;
1493
1494 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1495 if (!cp)
1496 return;
1497
1498 handle = __le16_to_cpu(cp->handle);
1499
1500 BT_DBG("%s handle %d", hdev->name, handle);
1501
1502 hci_dev_lock(hdev);
1503
1504 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001505 if (acl) {
1506 sco = acl->link;
1507 if (sco) {
1508 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001509
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001510 hci_proto_connect_cfm(sco, status);
1511 hci_conn_del(sco);
1512 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001513 }
1514
1515 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001516}
1517
1518static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1519{
1520 struct hci_cp_sniff_mode *cp;
1521 struct hci_conn *conn;
1522
1523 BT_DBG("%s status 0x%x", hdev->name, status);
1524
1525 if (!status)
1526 return;
1527
1528 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1529 if (!cp)
1530 return;
1531
1532 hci_dev_lock(hdev);
1533
1534 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001535 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001536 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001537
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001538 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001539 hci_sco_setup(conn, status);
1540 }
1541
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001542 hci_dev_unlock(hdev);
1543}
1544
1545static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1546{
1547 struct hci_cp_exit_sniff_mode *cp;
1548 struct hci_conn *conn;
1549
1550 BT_DBG("%s status 0x%x", hdev->name, status);
1551
1552 if (!status)
1553 return;
1554
1555 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1556 if (!cp)
1557 return;
1558
1559 hci_dev_lock(hdev);
1560
1561 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001562 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001563 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001564
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001565 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001566 hci_sco_setup(conn, status);
1567 }
1568
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001569 hci_dev_unlock(hdev);
1570}
1571
Johan Hedberg88c3df12012-02-09 14:27:38 +02001572static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1573{
1574 struct hci_cp_disconnect *cp;
1575 struct hci_conn *conn;
1576
1577 if (!status)
1578 return;
1579
1580 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1581 if (!cp)
1582 return;
1583
1584 hci_dev_lock(hdev);
1585
1586 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1587 if (conn)
1588 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1589 conn->dst_type, status);
1590
1591 hci_dev_unlock(hdev);
1592}
1593
Ville Tervofcd89c02011-02-10 22:38:47 -03001594static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1595{
1596 struct hci_cp_le_create_conn *cp;
1597 struct hci_conn *conn;
1598
1599 BT_DBG("%s status 0x%x", hdev->name, status);
1600
1601 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1602 if (!cp)
1603 return;
1604
1605 hci_dev_lock(hdev);
1606
1607 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1608
1609 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1610 conn);
1611
1612 if (status) {
1613 if (conn && conn->state == BT_CONNECT) {
1614 conn->state = BT_CLOSED;
1615 hci_proto_connect_cfm(conn, status);
1616 hci_conn_del(conn);
1617 }
1618 } else {
1619 if (!conn) {
1620 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001621 if (conn) {
1622 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001623 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001624 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001625 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001626 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001627 }
1628 }
1629
1630 hci_dev_unlock(hdev);
1631}
1632
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001633static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1634{
1635 BT_DBG("%s status 0x%x", hdev->name, status);
1636}
1637
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001638static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1639{
1640 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001641 struct discovery_state *discov = &hdev->discovery;
1642 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001643
1644 BT_DBG("%s status %d", hdev->name, status);
1645
Johan Hedberg23bb5762010-12-21 23:01:27 +02001646 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001647
1648 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001649
1650 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1651 return;
1652
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001653 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001654 return;
1655
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001656 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001657
Andre Guedes343f9352012-02-17 20:39:37 -03001658 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001659 goto unlock;
1660
1661 if (list_empty(&discov->resolve)) {
1662 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1663 goto unlock;
1664 }
1665
1666 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1667 if (e && hci_resolve_name(hdev, e) == 0) {
1668 e->name_state = NAME_PENDING;
1669 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1670 } else {
1671 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1672 }
1673
1674unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001675 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001676}
1677
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1679{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001680 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001681 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682 int num_rsp = *((__u8 *) skb->data);
1683
1684 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1685
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001686 if (!num_rsp)
1687 return;
1688
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001690
Johan Hedberge17acd42011-03-30 23:57:16 +03001691 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg31754052012-01-04 13:39:52 +02001692 bool name_known;
1693
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 bacpy(&data.bdaddr, &info->bdaddr);
1695 data.pscan_rep_mode = info->pscan_rep_mode;
1696 data.pscan_period_mode = info->pscan_period_mode;
1697 data.pscan_mode = info->pscan_mode;
1698 memcpy(data.dev_class, info->dev_class, 3);
1699 data.clock_offset = info->clock_offset;
1700 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001701 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001702
1703 name_known = hci_inquiry_cache_update(hdev, &data, false);
Johan Hedberg48264f02011-11-09 13:58:58 +02001704 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Andre Guedes7d262f82012-01-10 18:20:49 -03001705 info->dev_class, 0, !name_known,
1706 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001708
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 hci_dev_unlock(hdev);
1710}
1711
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001712static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001714 struct hci_ev_conn_complete *ev = (void *) skb->data;
1715 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001717 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001718
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001720
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001721 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001722 if (!conn) {
1723 if (ev->link_type != SCO_LINK)
1724 goto unlock;
1725
1726 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1727 if (!conn)
1728 goto unlock;
1729
1730 conn->type = SCO_LINK;
1731 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001732
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001733 if (!ev->status) {
1734 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001735
1736 if (conn->type == ACL_LINK) {
1737 conn->state = BT_CONFIG;
1738 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001739 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001740 } else
1741 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001742
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001743 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001744 hci_conn_add_sysfs(conn);
1745
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001746 if (test_bit(HCI_AUTH, &hdev->flags))
1747 conn->link_mode |= HCI_LM_AUTH;
1748
1749 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1750 conn->link_mode |= HCI_LM_ENCRYPT;
1751
1752 /* Get remote features */
1753 if (conn->type == ACL_LINK) {
1754 struct hci_cp_read_remote_features cp;
1755 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001756 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1757 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001758 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001759
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001760 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001761 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001762 struct hci_cp_change_conn_ptype cp;
1763 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001764 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1765 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1766 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001767 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001768 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001769 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001770 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001771 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001772 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001773 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001774
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001775 if (conn->type == ACL_LINK)
1776 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001777
Marcel Holtmann769be972008-07-14 20:13:49 +02001778 if (ev->status) {
1779 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001780 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001781 } else if (ev->link_type != ACL_LINK)
1782 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001783
1784unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001786
1787 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788}
1789
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1791{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001792 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 int mask = hdev->link_mode;
1794
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001795 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1796 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797
1798 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1799
Szymon Janc138d22e2011-02-17 16:44:23 +01001800 if ((mask & HCI_LM_ACCEPT) &&
1801 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001803 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805
1806 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001807
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001808 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1809 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001810 memcpy(ie->data.dev_class, ev->dev_class, 3);
1811
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1813 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001814 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1815 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001816 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 hci_dev_unlock(hdev);
1818 return;
1819 }
1820 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001821
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 memcpy(conn->dev_class, ev->dev_class, 3);
1823 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001824
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 hci_dev_unlock(hdev);
1826
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001827 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1828 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001830 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001832 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1833 cp.role = 0x00; /* Become master */
1834 else
1835 cp.role = 0x01; /* Remain slave */
1836
1837 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1838 sizeof(cp), &cp);
1839 } else {
1840 struct hci_cp_accept_sync_conn_req cp;
1841
1842 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001843 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001844
1845 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1846 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1847 cp.max_latency = cpu_to_le16(0xffff);
1848 cp.content_format = cpu_to_le16(hdev->voice_setting);
1849 cp.retrans_effort = 0xff;
1850
1851 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1852 sizeof(cp), &cp);
1853 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854 } else {
1855 /* Connection rejected */
1856 struct hci_cp_reject_conn_req cp;
1857
1858 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001859 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001860 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861 }
1862}
1863
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1865{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001866 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001867 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868
1869 BT_DBG("%s status %d", hdev->name, ev->status);
1870
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871 hci_dev_lock(hdev);
1872
Marcel Holtmann04837f62006-07-03 10:02:33 +02001873 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001874 if (!conn)
1875 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001876
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001877 if (ev->status == 0)
1878 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879
Johan Hedbergb644ba32012-01-17 21:48:47 +02001880 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1881 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001882 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001883 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1884 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001885 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001886 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001887 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001888 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001889
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001890 if (ev->status == 0) {
1891 hci_proto_disconn_cfm(conn, ev->reason);
1892 hci_conn_del(conn);
1893 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001894
1895unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 hci_dev_unlock(hdev);
1897}
1898
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001899static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1900{
1901 struct hci_ev_auth_complete *ev = (void *) skb->data;
1902 struct hci_conn *conn;
1903
1904 BT_DBG("%s status %d", hdev->name, ev->status);
1905
1906 hci_dev_lock(hdev);
1907
1908 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001909 if (!conn)
1910 goto unlock;
1911
1912 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001913 if (!hci_conn_ssp_enabled(conn) &&
1914 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001915 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001916 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001917 conn->link_mode |= HCI_LM_AUTH;
1918 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001919 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001920 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001921 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
1922 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001923 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001924
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001925 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1926 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001927
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001928 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001929 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001930 struct hci_cp_set_conn_encrypt cp;
1931 cp.handle = ev->handle;
1932 cp.encrypt = 0x01;
1933 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1934 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001935 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001936 conn->state = BT_CONNECTED;
1937 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001938 hci_conn_put(conn);
1939 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001940 } else {
1941 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001942
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001943 hci_conn_hold(conn);
1944 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1945 hci_conn_put(conn);
1946 }
1947
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001948 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001949 if (!ev->status) {
1950 struct hci_cp_set_conn_encrypt cp;
1951 cp.handle = ev->handle;
1952 cp.encrypt = 0x01;
1953 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1954 &cp);
1955 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001956 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001957 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001958 }
1959 }
1960
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001961unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001962 hci_dev_unlock(hdev);
1963}
1964
1965static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1966{
Johan Hedberg127178d2010-11-18 22:22:29 +02001967 struct hci_ev_remote_name *ev = (void *) skb->data;
1968 struct hci_conn *conn;
1969
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001970 BT_DBG("%s", hdev->name);
1971
1972 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001973
1974 hci_dev_lock(hdev);
1975
1976 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001977
1978 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1979 goto check_auth;
1980
1981 if (ev->status == 0)
1982 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1983 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1984 else
1985 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1986
1987check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001988 if (!conn)
1989 goto unlock;
1990
1991 if (!hci_outgoing_auth_needed(hdev, conn))
1992 goto unlock;
1993
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001994 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001995 struct hci_cp_auth_requested cp;
1996 cp.handle = __cpu_to_le16(conn->handle);
1997 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1998 }
1999
Johan Hedberg79c6c702011-04-28 11:28:55 -07002000unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002001 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002002}
2003
2004static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2005{
2006 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2007 struct hci_conn *conn;
2008
2009 BT_DBG("%s status %d", hdev->name, ev->status);
2010
2011 hci_dev_lock(hdev);
2012
2013 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2014 if (conn) {
2015 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002016 if (ev->encrypt) {
2017 /* Encryption implies authentication */
2018 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002019 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002020 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002021 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002022 conn->link_mode &= ~HCI_LM_ENCRYPT;
2023 }
2024
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002025 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002026
Marcel Holtmannf8558552008-07-14 20:13:49 +02002027 if (conn->state == BT_CONFIG) {
2028 if (!ev->status)
2029 conn->state = BT_CONNECTED;
2030
2031 hci_proto_connect_cfm(conn, ev->status);
2032 hci_conn_put(conn);
2033 } else
2034 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002035 }
2036
2037 hci_dev_unlock(hdev);
2038}
2039
2040static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2041{
2042 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2043 struct hci_conn *conn;
2044
2045 BT_DBG("%s status %d", hdev->name, ev->status);
2046
2047 hci_dev_lock(hdev);
2048
2049 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2050 if (conn) {
2051 if (!ev->status)
2052 conn->link_mode |= HCI_LM_SECURE;
2053
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002054 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002055
2056 hci_key_change_cfm(conn, ev->status);
2057 }
2058
2059 hci_dev_unlock(hdev);
2060}
2061
2062static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2063{
2064 struct hci_ev_remote_features *ev = (void *) skb->data;
2065 struct hci_conn *conn;
2066
2067 BT_DBG("%s status %d", hdev->name, ev->status);
2068
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002069 hci_dev_lock(hdev);
2070
2071 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002072 if (!conn)
2073 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002074
Johan Hedbergccd556f2010-11-10 17:11:51 +02002075 if (!ev->status)
2076 memcpy(conn->features, ev->features, 8);
2077
2078 if (conn->state != BT_CONFIG)
2079 goto unlock;
2080
2081 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2082 struct hci_cp_read_remote_ext_features cp;
2083 cp.handle = ev->handle;
2084 cp.page = 0x01;
2085 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002086 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002087 goto unlock;
2088 }
2089
Johan Hedberg127178d2010-11-18 22:22:29 +02002090 if (!ev->status) {
2091 struct hci_cp_remote_name_req cp;
2092 memset(&cp, 0, sizeof(cp));
2093 bacpy(&cp.bdaddr, &conn->dst);
2094 cp.pscan_rep_mode = 0x02;
2095 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002096 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2097 mgmt_device_connected(hdev, &conn->dst, conn->type,
2098 conn->dst_type, NULL, 0,
2099 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002100
Johan Hedberg127178d2010-11-18 22:22:29 +02002101 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002102 conn->state = BT_CONNECTED;
2103 hci_proto_connect_cfm(conn, ev->status);
2104 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002105 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002106
Johan Hedbergccd556f2010-11-10 17:11:51 +02002107unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002108 hci_dev_unlock(hdev);
2109}
2110
2111static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2112{
2113 BT_DBG("%s", hdev->name);
2114}
2115
2116static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2117{
2118 BT_DBG("%s", hdev->name);
2119}
2120
2121static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2122{
2123 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2124 __u16 opcode;
2125
2126 skb_pull(skb, sizeof(*ev));
2127
2128 opcode = __le16_to_cpu(ev->opcode);
2129
2130 switch (opcode) {
2131 case HCI_OP_INQUIRY_CANCEL:
2132 hci_cc_inquiry_cancel(hdev, skb);
2133 break;
2134
2135 case HCI_OP_EXIT_PERIODIC_INQ:
2136 hci_cc_exit_periodic_inq(hdev, skb);
2137 break;
2138
2139 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2140 hci_cc_remote_name_req_cancel(hdev, skb);
2141 break;
2142
2143 case HCI_OP_ROLE_DISCOVERY:
2144 hci_cc_role_discovery(hdev, skb);
2145 break;
2146
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002147 case HCI_OP_READ_LINK_POLICY:
2148 hci_cc_read_link_policy(hdev, skb);
2149 break;
2150
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002151 case HCI_OP_WRITE_LINK_POLICY:
2152 hci_cc_write_link_policy(hdev, skb);
2153 break;
2154
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002155 case HCI_OP_READ_DEF_LINK_POLICY:
2156 hci_cc_read_def_link_policy(hdev, skb);
2157 break;
2158
2159 case HCI_OP_WRITE_DEF_LINK_POLICY:
2160 hci_cc_write_def_link_policy(hdev, skb);
2161 break;
2162
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002163 case HCI_OP_RESET:
2164 hci_cc_reset(hdev, skb);
2165 break;
2166
2167 case HCI_OP_WRITE_LOCAL_NAME:
2168 hci_cc_write_local_name(hdev, skb);
2169 break;
2170
2171 case HCI_OP_READ_LOCAL_NAME:
2172 hci_cc_read_local_name(hdev, skb);
2173 break;
2174
2175 case HCI_OP_WRITE_AUTH_ENABLE:
2176 hci_cc_write_auth_enable(hdev, skb);
2177 break;
2178
2179 case HCI_OP_WRITE_ENCRYPT_MODE:
2180 hci_cc_write_encrypt_mode(hdev, skb);
2181 break;
2182
2183 case HCI_OP_WRITE_SCAN_ENABLE:
2184 hci_cc_write_scan_enable(hdev, skb);
2185 break;
2186
2187 case HCI_OP_READ_CLASS_OF_DEV:
2188 hci_cc_read_class_of_dev(hdev, skb);
2189 break;
2190
2191 case HCI_OP_WRITE_CLASS_OF_DEV:
2192 hci_cc_write_class_of_dev(hdev, skb);
2193 break;
2194
2195 case HCI_OP_READ_VOICE_SETTING:
2196 hci_cc_read_voice_setting(hdev, skb);
2197 break;
2198
2199 case HCI_OP_WRITE_VOICE_SETTING:
2200 hci_cc_write_voice_setting(hdev, skb);
2201 break;
2202
2203 case HCI_OP_HOST_BUFFER_SIZE:
2204 hci_cc_host_buffer_size(hdev, skb);
2205 break;
2206
Marcel Holtmann333140b2008-07-14 20:13:48 +02002207 case HCI_OP_WRITE_SSP_MODE:
2208 hci_cc_write_ssp_mode(hdev, skb);
2209 break;
2210
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002211 case HCI_OP_READ_LOCAL_VERSION:
2212 hci_cc_read_local_version(hdev, skb);
2213 break;
2214
2215 case HCI_OP_READ_LOCAL_COMMANDS:
2216 hci_cc_read_local_commands(hdev, skb);
2217 break;
2218
2219 case HCI_OP_READ_LOCAL_FEATURES:
2220 hci_cc_read_local_features(hdev, skb);
2221 break;
2222
Andre Guedes971e3a42011-06-30 19:20:52 -03002223 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2224 hci_cc_read_local_ext_features(hdev, skb);
2225 break;
2226
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002227 case HCI_OP_READ_BUFFER_SIZE:
2228 hci_cc_read_buffer_size(hdev, skb);
2229 break;
2230
2231 case HCI_OP_READ_BD_ADDR:
2232 hci_cc_read_bd_addr(hdev, skb);
2233 break;
2234
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002235 case HCI_OP_READ_DATA_BLOCK_SIZE:
2236 hci_cc_read_data_block_size(hdev, skb);
2237 break;
2238
Johan Hedberg23bb5762010-12-21 23:01:27 +02002239 case HCI_OP_WRITE_CA_TIMEOUT:
2240 hci_cc_write_ca_timeout(hdev, skb);
2241 break;
2242
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002243 case HCI_OP_READ_FLOW_CONTROL_MODE:
2244 hci_cc_read_flow_control_mode(hdev, skb);
2245 break;
2246
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002247 case HCI_OP_READ_LOCAL_AMP_INFO:
2248 hci_cc_read_local_amp_info(hdev, skb);
2249 break;
2250
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002251 case HCI_OP_DELETE_STORED_LINK_KEY:
2252 hci_cc_delete_stored_link_key(hdev, skb);
2253 break;
2254
Johan Hedbergd5859e22011-01-25 01:19:58 +02002255 case HCI_OP_SET_EVENT_MASK:
2256 hci_cc_set_event_mask(hdev, skb);
2257 break;
2258
2259 case HCI_OP_WRITE_INQUIRY_MODE:
2260 hci_cc_write_inquiry_mode(hdev, skb);
2261 break;
2262
2263 case HCI_OP_READ_INQ_RSP_TX_POWER:
2264 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2265 break;
2266
2267 case HCI_OP_SET_EVENT_FLT:
2268 hci_cc_set_event_flt(hdev, skb);
2269 break;
2270
Johan Hedberg980e1a52011-01-22 06:10:07 +02002271 case HCI_OP_PIN_CODE_REPLY:
2272 hci_cc_pin_code_reply(hdev, skb);
2273 break;
2274
2275 case HCI_OP_PIN_CODE_NEG_REPLY:
2276 hci_cc_pin_code_neg_reply(hdev, skb);
2277 break;
2278
Szymon Jancc35938b2011-03-22 13:12:21 +01002279 case HCI_OP_READ_LOCAL_OOB_DATA:
2280 hci_cc_read_local_oob_data_reply(hdev, skb);
2281 break;
2282
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002283 case HCI_OP_LE_READ_BUFFER_SIZE:
2284 hci_cc_le_read_buffer_size(hdev, skb);
2285 break;
2286
Johan Hedberga5c29682011-02-19 12:05:57 -03002287 case HCI_OP_USER_CONFIRM_REPLY:
2288 hci_cc_user_confirm_reply(hdev, skb);
2289 break;
2290
2291 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2292 hci_cc_user_confirm_neg_reply(hdev, skb);
2293 break;
2294
Brian Gix1143d452011-11-23 08:28:34 -08002295 case HCI_OP_USER_PASSKEY_REPLY:
2296 hci_cc_user_passkey_reply(hdev, skb);
2297 break;
2298
2299 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2300 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002301
2302 case HCI_OP_LE_SET_SCAN_PARAM:
2303 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002304 break;
2305
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002306 case HCI_OP_LE_SET_SCAN_ENABLE:
2307 hci_cc_le_set_scan_enable(hdev, skb);
2308 break;
2309
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002310 case HCI_OP_LE_LTK_REPLY:
2311 hci_cc_le_ltk_reply(hdev, skb);
2312 break;
2313
2314 case HCI_OP_LE_LTK_NEG_REPLY:
2315 hci_cc_le_ltk_neg_reply(hdev, skb);
2316 break;
2317
Andre Guedesf9b49302011-06-30 19:20:53 -03002318 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2319 hci_cc_write_le_host_supported(hdev, skb);
2320 break;
2321
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002322 default:
2323 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2324 break;
2325 }
2326
Ville Tervo6bd32322011-02-16 16:32:41 +02002327 if (ev->opcode != HCI_OP_NOP)
2328 del_timer(&hdev->cmd_timer);
2329
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002330 if (ev->ncmd) {
2331 atomic_set(&hdev->cmd_cnt, 1);
2332 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002333 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002334 }
2335}
2336
2337static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2338{
2339 struct hci_ev_cmd_status *ev = (void *) skb->data;
2340 __u16 opcode;
2341
2342 skb_pull(skb, sizeof(*ev));
2343
2344 opcode = __le16_to_cpu(ev->opcode);
2345
2346 switch (opcode) {
2347 case HCI_OP_INQUIRY:
2348 hci_cs_inquiry(hdev, ev->status);
2349 break;
2350
2351 case HCI_OP_CREATE_CONN:
2352 hci_cs_create_conn(hdev, ev->status);
2353 break;
2354
2355 case HCI_OP_ADD_SCO:
2356 hci_cs_add_sco(hdev, ev->status);
2357 break;
2358
Marcel Holtmannf8558552008-07-14 20:13:49 +02002359 case HCI_OP_AUTH_REQUESTED:
2360 hci_cs_auth_requested(hdev, ev->status);
2361 break;
2362
2363 case HCI_OP_SET_CONN_ENCRYPT:
2364 hci_cs_set_conn_encrypt(hdev, ev->status);
2365 break;
2366
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002367 case HCI_OP_REMOTE_NAME_REQ:
2368 hci_cs_remote_name_req(hdev, ev->status);
2369 break;
2370
Marcel Holtmann769be972008-07-14 20:13:49 +02002371 case HCI_OP_READ_REMOTE_FEATURES:
2372 hci_cs_read_remote_features(hdev, ev->status);
2373 break;
2374
2375 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2376 hci_cs_read_remote_ext_features(hdev, ev->status);
2377 break;
2378
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002379 case HCI_OP_SETUP_SYNC_CONN:
2380 hci_cs_setup_sync_conn(hdev, ev->status);
2381 break;
2382
2383 case HCI_OP_SNIFF_MODE:
2384 hci_cs_sniff_mode(hdev, ev->status);
2385 break;
2386
2387 case HCI_OP_EXIT_SNIFF_MODE:
2388 hci_cs_exit_sniff_mode(hdev, ev->status);
2389 break;
2390
Johan Hedberg8962ee72011-01-20 12:40:27 +02002391 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002392 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002393 break;
2394
Ville Tervofcd89c02011-02-10 22:38:47 -03002395 case HCI_OP_LE_CREATE_CONN:
2396 hci_cs_le_create_conn(hdev, ev->status);
2397 break;
2398
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002399 case HCI_OP_LE_START_ENC:
2400 hci_cs_le_start_enc(hdev, ev->status);
2401 break;
2402
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002403 default:
2404 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2405 break;
2406 }
2407
Ville Tervo6bd32322011-02-16 16:32:41 +02002408 if (ev->opcode != HCI_OP_NOP)
2409 del_timer(&hdev->cmd_timer);
2410
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002411 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002412 atomic_set(&hdev->cmd_cnt, 1);
2413 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002414 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002415 }
2416}
2417
2418static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2419{
2420 struct hci_ev_role_change *ev = (void *) skb->data;
2421 struct hci_conn *conn;
2422
2423 BT_DBG("%s status %d", hdev->name, ev->status);
2424
2425 hci_dev_lock(hdev);
2426
2427 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2428 if (conn) {
2429 if (!ev->status) {
2430 if (ev->role)
2431 conn->link_mode &= ~HCI_LM_MASTER;
2432 else
2433 conn->link_mode |= HCI_LM_MASTER;
2434 }
2435
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002436 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002437
2438 hci_role_switch_cfm(conn, ev->status, ev->role);
2439 }
2440
2441 hci_dev_unlock(hdev);
2442}
2443
Linus Torvalds1da177e2005-04-16 15:20:36 -07002444static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2445{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002446 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002447 int i;
2448
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002449 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2450 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2451 return;
2452 }
2453
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002454 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2455 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456 BT_DBG("%s bad parameters", hdev->name);
2457 return;
2458 }
2459
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002460 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2461
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002462 for (i = 0; i < ev->num_hndl; i++) {
2463 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002464 struct hci_conn *conn;
2465 __u16 handle, count;
2466
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002467 handle = __le16_to_cpu(info->handle);
2468 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002469
2470 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002471 if (!conn)
2472 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002474 conn->sent -= count;
2475
2476 switch (conn->type) {
2477 case ACL_LINK:
2478 hdev->acl_cnt += count;
2479 if (hdev->acl_cnt > hdev->acl_pkts)
2480 hdev->acl_cnt = hdev->acl_pkts;
2481 break;
2482
2483 case LE_LINK:
2484 if (hdev->le_pkts) {
2485 hdev->le_cnt += count;
2486 if (hdev->le_cnt > hdev->le_pkts)
2487 hdev->le_cnt = hdev->le_pkts;
2488 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002489 hdev->acl_cnt += count;
2490 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002491 hdev->acl_cnt = hdev->acl_pkts;
2492 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002493 break;
2494
2495 case SCO_LINK:
2496 hdev->sco_cnt += count;
2497 if (hdev->sco_cnt > hdev->sco_pkts)
2498 hdev->sco_cnt = hdev->sco_pkts;
2499 break;
2500
2501 default:
2502 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2503 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504 }
2505 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002506
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002507 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508}
2509
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002510static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2511 struct sk_buff *skb)
2512{
2513 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2514 int i;
2515
2516 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2517 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2518 return;
2519 }
2520
2521 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2522 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2523 BT_DBG("%s bad parameters", hdev->name);
2524 return;
2525 }
2526
2527 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2528 ev->num_hndl);
2529
2530 for (i = 0; i < ev->num_hndl; i++) {
2531 struct hci_comp_blocks_info *info = &ev->handles[i];
2532 struct hci_conn *conn;
2533 __u16 handle, block_count;
2534
2535 handle = __le16_to_cpu(info->handle);
2536 block_count = __le16_to_cpu(info->blocks);
2537
2538 conn = hci_conn_hash_lookup_handle(hdev, handle);
2539 if (!conn)
2540 continue;
2541
2542 conn->sent -= block_count;
2543
2544 switch (conn->type) {
2545 case ACL_LINK:
2546 hdev->block_cnt += block_count;
2547 if (hdev->block_cnt > hdev->num_blocks)
2548 hdev->block_cnt = hdev->num_blocks;
2549 break;
2550
2551 default:
2552 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2553 break;
2554 }
2555 }
2556
2557 queue_work(hdev->workqueue, &hdev->tx_work);
2558}
2559
Marcel Holtmann04837f62006-07-03 10:02:33 +02002560static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002562 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002563 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564
2565 BT_DBG("%s status %d", hdev->name, ev->status);
2566
2567 hci_dev_lock(hdev);
2568
Marcel Holtmann04837f62006-07-03 10:02:33 +02002569 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2570 if (conn) {
2571 conn->mode = ev->mode;
2572 conn->interval = __le16_to_cpu(ev->interval);
2573
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002574 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002575 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002576 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002577 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002578 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002579 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002580
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002581 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002582 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002583 }
2584
2585 hci_dev_unlock(hdev);
2586}
2587
Linus Torvalds1da177e2005-04-16 15:20:36 -07002588static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2589{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002590 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2591 struct hci_conn *conn;
2592
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002593 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002594
2595 hci_dev_lock(hdev);
2596
2597 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002598 if (!conn)
2599 goto unlock;
2600
2601 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002602 hci_conn_hold(conn);
2603 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2604 hci_conn_put(conn);
2605 }
2606
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002607 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002608 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2609 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002610 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002611 u8 secure;
2612
2613 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2614 secure = 1;
2615 else
2616 secure = 0;
2617
Johan Hedberg744cf192011-11-08 20:40:14 +02002618 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002619 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002620
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002621unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002622 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002623}
2624
Linus Torvalds1da177e2005-04-16 15:20:36 -07002625static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2626{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002627 struct hci_ev_link_key_req *ev = (void *) skb->data;
2628 struct hci_cp_link_key_reply cp;
2629 struct hci_conn *conn;
2630 struct link_key *key;
2631
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002632 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002633
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002634 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002635 return;
2636
2637 hci_dev_lock(hdev);
2638
2639 key = hci_find_link_key(hdev, &ev->bdaddr);
2640 if (!key) {
2641 BT_DBG("%s link key not found for %s", hdev->name,
2642 batostr(&ev->bdaddr));
2643 goto not_found;
2644 }
2645
2646 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2647 batostr(&ev->bdaddr));
2648
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002649 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002650 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002651 BT_DBG("%s ignoring debug key", hdev->name);
2652 goto not_found;
2653 }
2654
2655 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002656 if (conn) {
2657 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2658 conn->auth_type != 0xff &&
2659 (conn->auth_type & 0x01)) {
2660 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2661 goto not_found;
2662 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002663
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002664 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2665 conn->pending_sec_level == BT_SECURITY_HIGH) {
2666 BT_DBG("%s ignoring key unauthenticated for high \
2667 security", hdev->name);
2668 goto not_found;
2669 }
2670
2671 conn->key_type = key->type;
2672 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002673 }
2674
2675 bacpy(&cp.bdaddr, &ev->bdaddr);
2676 memcpy(cp.link_key, key->val, 16);
2677
2678 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2679
2680 hci_dev_unlock(hdev);
2681
2682 return;
2683
2684not_found:
2685 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2686 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002687}
2688
Linus Torvalds1da177e2005-04-16 15:20:36 -07002689static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2690{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002691 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2692 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002693 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002694
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002695 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002696
2697 hci_dev_lock(hdev);
2698
2699 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2700 if (conn) {
2701 hci_conn_hold(conn);
2702 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002703 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002704
2705 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2706 conn->key_type = ev->key_type;
2707
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002708 hci_conn_put(conn);
2709 }
2710
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002711 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002712 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002713 ev->key_type, pin_len);
2714
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002715 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716}
2717
Marcel Holtmann04837f62006-07-03 10:02:33 +02002718static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2719{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002720 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002721 struct hci_conn *conn;
2722
2723 BT_DBG("%s status %d", hdev->name, ev->status);
2724
2725 hci_dev_lock(hdev);
2726
2727 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728 if (conn && !ev->status) {
2729 struct inquiry_entry *ie;
2730
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002731 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2732 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002733 ie->data.clock_offset = ev->clock_offset;
2734 ie->timestamp = jiffies;
2735 }
2736 }
2737
2738 hci_dev_unlock(hdev);
2739}
2740
Marcel Holtmanna8746412008-07-14 20:13:46 +02002741static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2742{
2743 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2744 struct hci_conn *conn;
2745
2746 BT_DBG("%s status %d", hdev->name, ev->status);
2747
2748 hci_dev_lock(hdev);
2749
2750 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2751 if (conn && !ev->status)
2752 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2753
2754 hci_dev_unlock(hdev);
2755}
2756
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002757static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2758{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002759 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002760 struct inquiry_entry *ie;
2761
2762 BT_DBG("%s", hdev->name);
2763
2764 hci_dev_lock(hdev);
2765
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002766 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2767 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002768 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2769 ie->timestamp = jiffies;
2770 }
2771
2772 hci_dev_unlock(hdev);
2773}
2774
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002775static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2776{
2777 struct inquiry_data data;
2778 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg31754052012-01-04 13:39:52 +02002779 bool name_known;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002780
2781 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2782
2783 if (!num_rsp)
2784 return;
2785
2786 hci_dev_lock(hdev);
2787
2788 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002789 struct inquiry_info_with_rssi_and_pscan_mode *info;
2790 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002791
Johan Hedberge17acd42011-03-30 23:57:16 +03002792 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002793 bacpy(&data.bdaddr, &info->bdaddr);
2794 data.pscan_rep_mode = info->pscan_rep_mode;
2795 data.pscan_period_mode = info->pscan_period_mode;
2796 data.pscan_mode = info->pscan_mode;
2797 memcpy(data.dev_class, info->dev_class, 3);
2798 data.clock_offset = info->clock_offset;
2799 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002800 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002801
2802 name_known = hci_inquiry_cache_update(hdev, &data,
2803 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002804 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002805 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002806 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002807 }
2808 } else {
2809 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2810
Johan Hedberge17acd42011-03-30 23:57:16 +03002811 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002812 bacpy(&data.bdaddr, &info->bdaddr);
2813 data.pscan_rep_mode = info->pscan_rep_mode;
2814 data.pscan_period_mode = info->pscan_period_mode;
2815 data.pscan_mode = 0x00;
2816 memcpy(data.dev_class, info->dev_class, 3);
2817 data.clock_offset = info->clock_offset;
2818 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002819 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002820 name_known = hci_inquiry_cache_update(hdev, &data,
2821 false);
Johan Hedberg48264f02011-11-09 13:58:58 +02002822 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002823 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002824 !name_known, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002825 }
2826 }
2827
2828 hci_dev_unlock(hdev);
2829}
2830
2831static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2832{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002833 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2834 struct hci_conn *conn;
2835
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002836 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002837
Marcel Holtmann41a96212008-07-14 20:13:48 +02002838 hci_dev_lock(hdev);
2839
2840 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002841 if (!conn)
2842 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002843
Johan Hedbergccd556f2010-11-10 17:11:51 +02002844 if (!ev->status && ev->page == 0x01) {
2845 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002846
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002847 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2848 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002849 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002850
Johan Hedberg58a681e2012-01-16 06:47:28 +02002851 if (ev->features[0] & 0x01)
2852 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002853 }
2854
Johan Hedbergccd556f2010-11-10 17:11:51 +02002855 if (conn->state != BT_CONFIG)
2856 goto unlock;
2857
Johan Hedberg127178d2010-11-18 22:22:29 +02002858 if (!ev->status) {
2859 struct hci_cp_remote_name_req cp;
2860 memset(&cp, 0, sizeof(cp));
2861 bacpy(&cp.bdaddr, &conn->dst);
2862 cp.pscan_rep_mode = 0x02;
2863 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002864 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2865 mgmt_device_connected(hdev, &conn->dst, conn->type,
2866 conn->dst_type, NULL, 0,
2867 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002868
Johan Hedberg127178d2010-11-18 22:22:29 +02002869 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002870 conn->state = BT_CONNECTED;
2871 hci_proto_connect_cfm(conn, ev->status);
2872 hci_conn_put(conn);
2873 }
2874
2875unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002876 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002877}
2878
2879static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2880{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002881 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2882 struct hci_conn *conn;
2883
2884 BT_DBG("%s status %d", hdev->name, ev->status);
2885
2886 hci_dev_lock(hdev);
2887
2888 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002889 if (!conn) {
2890 if (ev->link_type == ESCO_LINK)
2891 goto unlock;
2892
2893 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2894 if (!conn)
2895 goto unlock;
2896
2897 conn->type = SCO_LINK;
2898 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002899
Marcel Holtmann732547f2009-04-19 19:14:14 +02002900 switch (ev->status) {
2901 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002902 conn->handle = __le16_to_cpu(ev->handle);
2903 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002904
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002905 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002906 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002907 break;
2908
Stephen Coe705e5712010-02-16 11:29:44 -05002909 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002910 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002911 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002912 case 0x1f: /* Unspecified error */
2913 if (conn->out && conn->attempt < 2) {
2914 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2915 (hdev->esco_type & EDR_ESCO_MASK);
2916 hci_setup_sync(conn, conn->link->handle);
2917 goto unlock;
2918 }
2919 /* fall through */
2920
2921 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002922 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002923 break;
2924 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002925
2926 hci_proto_connect_cfm(conn, ev->status);
2927 if (ev->status)
2928 hci_conn_del(conn);
2929
2930unlock:
2931 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002932}
2933
2934static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2935{
2936 BT_DBG("%s", hdev->name);
2937}
2938
Marcel Holtmann04837f62006-07-03 10:02:33 +02002939static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2940{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002941 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002942
2943 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002944}
2945
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002946static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2947{
2948 struct inquiry_data data;
2949 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2950 int num_rsp = *((__u8 *) skb->data);
2951
2952 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2953
2954 if (!num_rsp)
2955 return;
2956
2957 hci_dev_lock(hdev);
2958
Johan Hedberge17acd42011-03-30 23:57:16 +03002959 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg561aafb2012-01-04 13:31:59 +02002960 bool name_known;
2961
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002962 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002963 data.pscan_rep_mode = info->pscan_rep_mode;
2964 data.pscan_period_mode = info->pscan_period_mode;
2965 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002966 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002967 data.clock_offset = info->clock_offset;
2968 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002969 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002970
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002971 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002972 name_known = eir_has_data_type(info->data,
2973 sizeof(info->data),
2974 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002975 else
2976 name_known = true;
2977
Johan Hedberg31754052012-01-04 13:39:52 +02002978 name_known = hci_inquiry_cache_update(hdev, &data, name_known);
Johan Hedberg48264f02011-11-09 13:58:58 +02002979 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002980 info->dev_class, info->rssi,
Andre Guedes7d262f82012-01-10 18:20:49 -03002981 !name_known, info->data,
2982 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002983 }
2984
2985 hci_dev_unlock(hdev);
2986}
2987
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002988static inline u8 hci_get_auth_req(struct hci_conn *conn)
2989{
2990 /* If remote requests dedicated bonding follow that lead */
2991 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2992 /* If both remote and local IO capabilities allow MITM
2993 * protection then require it, otherwise don't */
2994 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2995 return 0x02;
2996 else
2997 return 0x03;
2998 }
2999
3000 /* If remote requests no-bonding follow that lead */
3001 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003002 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003003
3004 return conn->auth_type;
3005}
3006
Marcel Holtmann04936842008-07-14 20:13:48 +02003007static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3008{
3009 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3010 struct hci_conn *conn;
3011
3012 BT_DBG("%s", hdev->name);
3013
3014 hci_dev_lock(hdev);
3015
3016 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003017 if (!conn)
3018 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003019
Johan Hedberg03b555e2011-01-04 15:40:05 +02003020 hci_conn_hold(conn);
3021
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003022 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003023 goto unlock;
3024
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003025 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003026 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003027 struct hci_cp_io_capability_reply cp;
3028
3029 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303030 /* Change the IO capability from KeyboardDisplay
3031 * to DisplayYesNo as it is not supported by BT spec. */
3032 cp.capability = (conn->io_capability == 0x04) ?
3033 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003034 conn->auth_type = hci_get_auth_req(conn);
3035 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003036
Johan Hedberg58a681e2012-01-16 06:47:28 +02003037 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003038 hci_find_remote_oob_data(hdev, &conn->dst))
3039 cp.oob_data = 0x01;
3040 else
3041 cp.oob_data = 0x00;
3042
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003043 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3044 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003045 } else {
3046 struct hci_cp_io_capability_neg_reply cp;
3047
3048 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003049 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003050
3051 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3052 sizeof(cp), &cp);
3053 }
3054
3055unlock:
3056 hci_dev_unlock(hdev);
3057}
3058
3059static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3060{
3061 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3062 struct hci_conn *conn;
3063
3064 BT_DBG("%s", hdev->name);
3065
3066 hci_dev_lock(hdev);
3067
3068 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3069 if (!conn)
3070 goto unlock;
3071
Johan Hedberg03b555e2011-01-04 15:40:05 +02003072 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003073 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003074 if (ev->oob_data)
3075 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003076
3077unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003078 hci_dev_unlock(hdev);
3079}
3080
Johan Hedberga5c29682011-02-19 12:05:57 -03003081static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3082 struct sk_buff *skb)
3083{
3084 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003085 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003086 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003087
3088 BT_DBG("%s", hdev->name);
3089
3090 hci_dev_lock(hdev);
3091
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003092 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003093 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003094
Johan Hedberg7a828902011-04-28 11:28:53 -07003095 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3096 if (!conn)
3097 goto unlock;
3098
3099 loc_mitm = (conn->auth_type & 0x01);
3100 rem_mitm = (conn->remote_auth & 0x01);
3101
3102 /* If we require MITM but the remote device can't provide that
3103 * (it has NoInputNoOutput) then reject the confirmation
3104 * request. The only exception is when we're dedicated bonding
3105 * initiators (connect_cfm_cb set) since then we always have the MITM
3106 * bit set. */
3107 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3108 BT_DBG("Rejecting request: remote device can't provide MITM");
3109 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3110 sizeof(ev->bdaddr), &ev->bdaddr);
3111 goto unlock;
3112 }
3113
3114 /* If no side requires MITM protection; auto-accept */
3115 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3116 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003117
3118 /* If we're not the initiators request authorization to
3119 * proceed from user space (mgmt_user_confirm with
3120 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003121 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003122 BT_DBG("Confirming auto-accept as acceptor");
3123 confirm_hint = 1;
3124 goto confirm;
3125 }
3126
Johan Hedberg9f616562011-04-28 11:28:54 -07003127 BT_DBG("Auto-accept of user confirmation with %ums delay",
3128 hdev->auto_accept_delay);
3129
3130 if (hdev->auto_accept_delay > 0) {
3131 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3132 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3133 goto unlock;
3134 }
3135
Johan Hedberg7a828902011-04-28 11:28:53 -07003136 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3137 sizeof(ev->bdaddr), &ev->bdaddr);
3138 goto unlock;
3139 }
3140
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003141confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003142 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003143 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003144
3145unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003146 hci_dev_unlock(hdev);
3147}
3148
Brian Gix1143d452011-11-23 08:28:34 -08003149static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3150 struct sk_buff *skb)
3151{
3152 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3153
3154 BT_DBG("%s", hdev->name);
3155
3156 hci_dev_lock(hdev);
3157
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003158 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003159 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003160
3161 hci_dev_unlock(hdev);
3162}
3163
Marcel Holtmann04936842008-07-14 20:13:48 +02003164static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3165{
3166 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3167 struct hci_conn *conn;
3168
3169 BT_DBG("%s", hdev->name);
3170
3171 hci_dev_lock(hdev);
3172
3173 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003174 if (!conn)
3175 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003176
Johan Hedberg2a611692011-02-19 12:06:00 -03003177 /* To avoid duplicate auth_failed events to user space we check
3178 * the HCI_CONN_AUTH_PEND flag which will be set if we
3179 * initiated the authentication. A traditional auth_complete
3180 * event gets always produced as initiator and is also mapped to
3181 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003182 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003183 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3184 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003185
3186 hci_conn_put(conn);
3187
3188unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003189 hci_dev_unlock(hdev);
3190}
3191
Marcel Holtmann41a96212008-07-14 20:13:48 +02003192static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3193{
3194 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3195 struct inquiry_entry *ie;
3196
3197 BT_DBG("%s", hdev->name);
3198
3199 hci_dev_lock(hdev);
3200
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003201 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3202 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003203 ie->data.ssp_mode = (ev->features[0] & 0x01);
3204
3205 hci_dev_unlock(hdev);
3206}
3207
Szymon Janc2763eda2011-03-22 13:12:22 +01003208static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3209 struct sk_buff *skb)
3210{
3211 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3212 struct oob_data *data;
3213
3214 BT_DBG("%s", hdev->name);
3215
3216 hci_dev_lock(hdev);
3217
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003218 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003219 goto unlock;
3220
Szymon Janc2763eda2011-03-22 13:12:22 +01003221 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3222 if (data) {
3223 struct hci_cp_remote_oob_data_reply cp;
3224
3225 bacpy(&cp.bdaddr, &ev->bdaddr);
3226 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3227 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3228
3229 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3230 &cp);
3231 } else {
3232 struct hci_cp_remote_oob_data_neg_reply cp;
3233
3234 bacpy(&cp.bdaddr, &ev->bdaddr);
3235 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3236 &cp);
3237 }
3238
Szymon Jance1ba1f12011-04-06 13:01:59 +02003239unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003240 hci_dev_unlock(hdev);
3241}
3242
Ville Tervofcd89c02011-02-10 22:38:47 -03003243static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3244{
3245 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3246 struct hci_conn *conn;
3247
3248 BT_DBG("%s status %d", hdev->name, ev->status);
3249
3250 hci_dev_lock(hdev);
3251
3252 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003253 if (!conn) {
3254 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3255 if (!conn) {
3256 BT_ERR("No memory for new connection");
3257 hci_dev_unlock(hdev);
3258 return;
3259 }
Andre Guedes29b79882011-05-31 14:20:54 -03003260
3261 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003262 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003263
3264 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003265 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3266 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003267 hci_proto_connect_cfm(conn, ev->status);
3268 conn->state = BT_CLOSED;
3269 hci_conn_del(conn);
3270 goto unlock;
3271 }
3272
Johan Hedbergb644ba32012-01-17 21:48:47 +02003273 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3274 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3275 conn->dst_type, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003276
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003277 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003278 conn->handle = __le16_to_cpu(ev->handle);
3279 conn->state = BT_CONNECTED;
3280
3281 hci_conn_hold_device(conn);
3282 hci_conn_add_sysfs(conn);
3283
3284 hci_proto_connect_cfm(conn, ev->status);
3285
3286unlock:
3287 hci_dev_unlock(hdev);
3288}
3289
Andre Guedes9aa04c92011-05-26 16:23:51 -03003290static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3291 struct sk_buff *skb)
3292{
Andre Guedese95beb42011-09-26 20:48:35 -03003293 u8 num_reports = skb->data[0];
3294 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003295 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003296
3297 hci_dev_lock(hdev);
3298
Andre Guedese95beb42011-09-26 20:48:35 -03003299 while (num_reports--) {
3300 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003301
Andre Guedes9aa04c92011-05-26 16:23:51 -03003302 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003303
Andre Guedes3c9e9192012-01-10 18:20:50 -03003304 rssi = ev->data[ev->length];
3305 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3306 NULL, rssi, 0, ev->data, ev->length);
3307
Andre Guedese95beb42011-09-26 20:48:35 -03003308 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003309 }
3310
3311 hci_dev_unlock(hdev);
3312}
3313
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003314static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3315 struct sk_buff *skb)
3316{
3317 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3318 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003319 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003320 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003321 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003322
3323 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3324
3325 hci_dev_lock(hdev);
3326
3327 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003328 if (conn == NULL)
3329 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003330
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003331 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3332 if (ltk == NULL)
3333 goto not_found;
3334
3335 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003336 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003337
3338 if (ltk->authenticated)
3339 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003340
3341 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3342
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003343 if (ltk->type & HCI_SMP_STK) {
3344 list_del(&ltk->list);
3345 kfree(ltk);
3346 }
3347
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003348 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003349
3350 return;
3351
3352not_found:
3353 neg.handle = ev->handle;
3354 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3355 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003356}
3357
Ville Tervofcd89c02011-02-10 22:38:47 -03003358static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3359{
3360 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3361
3362 skb_pull(skb, sizeof(*le_ev));
3363
3364 switch (le_ev->subevent) {
3365 case HCI_EV_LE_CONN_COMPLETE:
3366 hci_le_conn_complete_evt(hdev, skb);
3367 break;
3368
Andre Guedes9aa04c92011-05-26 16:23:51 -03003369 case HCI_EV_LE_ADVERTISING_REPORT:
3370 hci_le_adv_report_evt(hdev, skb);
3371 break;
3372
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003373 case HCI_EV_LE_LTK_REQ:
3374 hci_le_ltk_request_evt(hdev, skb);
3375 break;
3376
Ville Tervofcd89c02011-02-10 22:38:47 -03003377 default:
3378 break;
3379 }
3380}
3381
Linus Torvalds1da177e2005-04-16 15:20:36 -07003382void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3383{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003384 struct hci_event_hdr *hdr = (void *) skb->data;
3385 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003386
3387 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3388
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003389 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003390 case HCI_EV_INQUIRY_COMPLETE:
3391 hci_inquiry_complete_evt(hdev, skb);
3392 break;
3393
3394 case HCI_EV_INQUIRY_RESULT:
3395 hci_inquiry_result_evt(hdev, skb);
3396 break;
3397
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003398 case HCI_EV_CONN_COMPLETE:
3399 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003400 break;
3401
Linus Torvalds1da177e2005-04-16 15:20:36 -07003402 case HCI_EV_CONN_REQUEST:
3403 hci_conn_request_evt(hdev, skb);
3404 break;
3405
Linus Torvalds1da177e2005-04-16 15:20:36 -07003406 case HCI_EV_DISCONN_COMPLETE:
3407 hci_disconn_complete_evt(hdev, skb);
3408 break;
3409
Linus Torvalds1da177e2005-04-16 15:20:36 -07003410 case HCI_EV_AUTH_COMPLETE:
3411 hci_auth_complete_evt(hdev, skb);
3412 break;
3413
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003414 case HCI_EV_REMOTE_NAME:
3415 hci_remote_name_evt(hdev, skb);
3416 break;
3417
Linus Torvalds1da177e2005-04-16 15:20:36 -07003418 case HCI_EV_ENCRYPT_CHANGE:
3419 hci_encrypt_change_evt(hdev, skb);
3420 break;
3421
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003422 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3423 hci_change_link_key_complete_evt(hdev, skb);
3424 break;
3425
3426 case HCI_EV_REMOTE_FEATURES:
3427 hci_remote_features_evt(hdev, skb);
3428 break;
3429
3430 case HCI_EV_REMOTE_VERSION:
3431 hci_remote_version_evt(hdev, skb);
3432 break;
3433
3434 case HCI_EV_QOS_SETUP_COMPLETE:
3435 hci_qos_setup_complete_evt(hdev, skb);
3436 break;
3437
3438 case HCI_EV_CMD_COMPLETE:
3439 hci_cmd_complete_evt(hdev, skb);
3440 break;
3441
3442 case HCI_EV_CMD_STATUS:
3443 hci_cmd_status_evt(hdev, skb);
3444 break;
3445
3446 case HCI_EV_ROLE_CHANGE:
3447 hci_role_change_evt(hdev, skb);
3448 break;
3449
3450 case HCI_EV_NUM_COMP_PKTS:
3451 hci_num_comp_pkts_evt(hdev, skb);
3452 break;
3453
3454 case HCI_EV_MODE_CHANGE:
3455 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003456 break;
3457
3458 case HCI_EV_PIN_CODE_REQ:
3459 hci_pin_code_request_evt(hdev, skb);
3460 break;
3461
3462 case HCI_EV_LINK_KEY_REQ:
3463 hci_link_key_request_evt(hdev, skb);
3464 break;
3465
3466 case HCI_EV_LINK_KEY_NOTIFY:
3467 hci_link_key_notify_evt(hdev, skb);
3468 break;
3469
3470 case HCI_EV_CLOCK_OFFSET:
3471 hci_clock_offset_evt(hdev, skb);
3472 break;
3473
Marcel Holtmanna8746412008-07-14 20:13:46 +02003474 case HCI_EV_PKT_TYPE_CHANGE:
3475 hci_pkt_type_change_evt(hdev, skb);
3476 break;
3477
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003478 case HCI_EV_PSCAN_REP_MODE:
3479 hci_pscan_rep_mode_evt(hdev, skb);
3480 break;
3481
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003482 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3483 hci_inquiry_result_with_rssi_evt(hdev, skb);
3484 break;
3485
3486 case HCI_EV_REMOTE_EXT_FEATURES:
3487 hci_remote_ext_features_evt(hdev, skb);
3488 break;
3489
3490 case HCI_EV_SYNC_CONN_COMPLETE:
3491 hci_sync_conn_complete_evt(hdev, skb);
3492 break;
3493
3494 case HCI_EV_SYNC_CONN_CHANGED:
3495 hci_sync_conn_changed_evt(hdev, skb);
3496 break;
3497
Marcel Holtmann04837f62006-07-03 10:02:33 +02003498 case HCI_EV_SNIFF_SUBRATE:
3499 hci_sniff_subrate_evt(hdev, skb);
3500 break;
3501
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003502 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3503 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003504 break;
3505
Marcel Holtmann04936842008-07-14 20:13:48 +02003506 case HCI_EV_IO_CAPA_REQUEST:
3507 hci_io_capa_request_evt(hdev, skb);
3508 break;
3509
Johan Hedberg03b555e2011-01-04 15:40:05 +02003510 case HCI_EV_IO_CAPA_REPLY:
3511 hci_io_capa_reply_evt(hdev, skb);
3512 break;
3513
Johan Hedberga5c29682011-02-19 12:05:57 -03003514 case HCI_EV_USER_CONFIRM_REQUEST:
3515 hci_user_confirm_request_evt(hdev, skb);
3516 break;
3517
Brian Gix1143d452011-11-23 08:28:34 -08003518 case HCI_EV_USER_PASSKEY_REQUEST:
3519 hci_user_passkey_request_evt(hdev, skb);
3520 break;
3521
Marcel Holtmann04936842008-07-14 20:13:48 +02003522 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3523 hci_simple_pair_complete_evt(hdev, skb);
3524 break;
3525
Marcel Holtmann41a96212008-07-14 20:13:48 +02003526 case HCI_EV_REMOTE_HOST_FEATURES:
3527 hci_remote_host_features_evt(hdev, skb);
3528 break;
3529
Ville Tervofcd89c02011-02-10 22:38:47 -03003530 case HCI_EV_LE_META:
3531 hci_le_meta_evt(hdev, skb);
3532 break;
3533
Szymon Janc2763eda2011-03-22 13:12:22 +01003534 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3535 hci_remote_oob_data_request_evt(hdev, skb);
3536 break;
3537
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003538 case HCI_EV_NUM_COMP_BLOCKS:
3539 hci_num_comp_blocks_evt(hdev, skb);
3540 break;
3541
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003542 default:
3543 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003544 break;
3545 }
3546
3547 kfree_skb(skb);
3548 hdev->stat.evt_rx++;
3549}