blob: 221a185cc951607e82ff353d69ed7bfdd61a1c44 [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 <asm/unaligned.h>
28
29#include <net/bluetooth/bluetooth.h>
30#include <net/bluetooth/hci_core.h>
Mikel Astizf0d6a0e2012-08-09 09:52:30 +020031#include <net/bluetooth/mgmt.h>
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +030032#include <net/bluetooth/a2mp.h>
Andrei Emeltchenko903e4542012-09-27 17:26:09 +030033#include <net/bluetooth/amp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Linus Torvalds1da177e2005-04-16 15:20:36 -070035/* Handle HCI Event packets */
36
Marcel Holtmanna9de9242007-10-20 13:33:56 +020037static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070038{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020039 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030041 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Andre Guedes82f47852013-04-30 15:29:34 -030043 if (status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020044 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
Andre Guedes89352e72011-11-04 14:16:53 -030046 clear_bit(HCI_INQUIRY, &hdev->flags);
Andre Guedes3e13fa12013-03-27 20:04:56 -030047 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
48 wake_up_bit(&hdev->flags, HCI_INQUIRY);
Andre Guedes89352e72011-11-04 14:16:53 -030049
Marcel Holtmanna9de9242007-10-20 13:33:56 +020050 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051}
52
Andre Guedes4d934832012-03-21 00:03:35 -030053static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
54{
55 __u8 status = *((__u8 *) skb->data);
56
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030057 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030058
59 if (status)
60 return;
61
62 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030063}
64
Marcel Holtmanna9de9242007-10-20 13:33:56 +020065static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070066{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020067 __u8 status = *((__u8 *) skb->data);
68
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030069 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020070
71 if (status)
72 return;
73
Andre Guedesae854a72012-03-21 00:03:36 -030074 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
75
Marcel Holtmanna9de9242007-10-20 13:33:56 +020076 hci_conn_check_pending(hdev);
77}
78
Gustavo Padovan807deac2012-05-17 00:36:24 -030079static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
80 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020081{
82 BT_DBG("%s", hdev->name);
83}
84
85static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
86{
87 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030090 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
Marcel Holtmanna9de9242007-10-20 13:33:56 +020092 if (rp->status)
93 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
98 if (conn) {
99 if (rp->role)
100 conn->link_mode &= ~HCI_LM_MASTER;
101 else
102 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200104
105 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106}
107
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200108static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
109{
110 struct hci_rp_read_link_policy *rp = (void *) skb->data;
111 struct hci_conn *conn;
112
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300113 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200114
115 if (rp->status)
116 return;
117
118 hci_dev_lock(hdev);
119
120 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
121 if (conn)
122 conn->link_policy = __le16_to_cpu(rp->policy);
123
124 hci_dev_unlock(hdev);
125}
126
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200127static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200129 struct hci_rp_write_link_policy *rp = (void *) skb->data;
130 struct hci_conn *conn;
131 void *sent;
132
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300133 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200134
135 if (rp->status)
136 return;
137
138 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
139 if (!sent)
140 return;
141
142 hci_dev_lock(hdev);
143
144 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200145 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700146 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200147
148 hci_dev_unlock(hdev);
149}
150
Gustavo Padovan807deac2012-05-17 00:36:24 -0300151static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
152 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200153{
154 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
155
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300156 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200157
158 if (rp->status)
159 return;
160
161 hdev->link_policy = __le16_to_cpu(rp->policy);
162}
163
Gustavo Padovan807deac2012-05-17 00:36:24 -0300164static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
165 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200166{
167 __u8 status = *((__u8 *) skb->data);
168 void *sent;
169
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300170 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200171
172 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
173 if (!sent)
174 return;
175
176 if (!status)
177 hdev->link_policy = get_unaligned_le16(sent);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200178}
179
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200180static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
181{
182 __u8 status = *((__u8 *) skb->data);
183
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300184 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200185
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300186 clear_bit(HCI_RESET, &hdev->flags);
187
Johan Hedberga297e972012-02-21 17:55:47 +0200188 /* Reset all non-persistent flags */
Johan Hedberg2cc6fb02013-03-15 17:06:57 -0500189 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
Andre Guedes69775ff2012-02-23 16:50:05 +0200190
191 hdev->discovery.state = DISCOVERY_STOPPED;
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100192 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
193 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100194
195 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
196 hdev->adv_data_len = 0;
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
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300204 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200205
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 Hedbergf51d5b22012-02-22 18:17:32 +0200212 if (test_bit(HCI_MGMT, &hdev->dev_flags))
213 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200214 else if (!status)
215 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200216
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200217 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200218}
219
220static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
221{
222 struct hci_rp_read_local_name *rp = (void *) skb->data;
223
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300224 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200225
226 if (rp->status)
227 return;
228
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200229 if (test_bit(HCI_SETUP, &hdev->dev_flags))
230 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200231}
232
233static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
234{
235 __u8 status = *((__u8 *) skb->data);
236 void *sent;
237
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300238 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200239
240 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
241 if (!sent)
242 return;
243
244 if (!status) {
245 __u8 param = *((__u8 *) sent);
246
247 if (param == AUTH_ENABLED)
248 set_bit(HCI_AUTH, &hdev->flags);
249 else
250 clear_bit(HCI_AUTH, &hdev->flags);
251 }
252
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200253 if (test_bit(HCI_MGMT, &hdev->dev_flags))
254 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200255}
256
257static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
258{
259 __u8 status = *((__u8 *) skb->data);
260 void *sent;
261
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300262 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200263
264 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
265 if (!sent)
266 return;
267
268 if (!status) {
269 __u8 param = *((__u8 *) sent);
270
271 if (param)
272 set_bit(HCI_ENCRYPT, &hdev->flags);
273 else
274 clear_bit(HCI_ENCRYPT, &hdev->flags);
275 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200276}
277
278static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
279{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200280 __u8 param, status = *((__u8 *) skb->data);
281 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200282 void *sent;
283
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300284 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200285
286 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
287 if (!sent)
288 return;
289
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200290 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200291
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200292 hci_dev_lock(hdev);
293
Mikel Astizfa1bd912012-08-09 09:52:29 +0200294 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200295 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200296 hdev->discov_timeout = 0;
297 goto done;
298 }
299
Johan Hedberg0663ca22013-10-02 13:43:14 +0300300 /* We need to ensure that we set this back on if someone changed
301 * the scan mode through a raw HCI socket.
302 */
303 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
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,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300315 to);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200316 }
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);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200329}
330
331static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
332{
333 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
334
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300335 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200336
337 if (rp->status)
338 return;
339
340 memcpy(hdev->dev_class, rp->dev_class, 3);
341
342 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300343 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200344}
345
346static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
347{
348 __u8 status = *((__u8 *) skb->data);
349 void *sent;
350
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300351 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200352
353 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
354 if (!sent)
355 return;
356
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100357 hci_dev_lock(hdev);
358
359 if (status == 0)
360 memcpy(hdev->dev_class, sent, 3);
361
362 if (test_bit(HCI_MGMT, &hdev->dev_flags))
363 mgmt_set_class_of_dev_complete(hdev, sent, status);
364
365 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200366}
367
368static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
369{
370 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200372
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300373 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200374
375 if (rp->status)
376 return;
377
378 setting = __le16_to_cpu(rp->voice_setting);
379
Marcel Holtmannf383f272008-07-14 20:13:47 +0200380 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200381 return;
382
383 hdev->voice_setting = setting;
384
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300385 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200386
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200387 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200388 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389}
390
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300391static void hci_cc_write_voice_setting(struct hci_dev *hdev,
392 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200393{
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
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300398 BT_DBG("%s status 0x%2.2x", 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
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300414 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200415
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 Holtmann333140b2008-07-14 20:13:48 +0200420static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
421{
422 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300423 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200424
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300425 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200426
Marcel Holtmann333140b2008-07-14 20:13:48 +0200427 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
428 if (!sent)
429 return;
430
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300431 if (!status) {
432 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300433 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300434 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300435 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300436 }
437
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200438 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300439 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200440 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300441 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200442 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
443 else
444 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
445 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200446}
447
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200448static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
449{
450 struct hci_rp_read_local_version *rp = (void *) skb->data;
451
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300452 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200453
454 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200455 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200456
457 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200458 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200459 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200460 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200461 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200462
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300463 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300464 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200465}
466
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300467static void hci_cc_read_local_commands(struct hci_dev *hdev,
468 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200469{
470 struct hci_rp_read_local_commands *rp = (void *) skb->data;
471
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300472 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200473
Johan Hedberg2177bab2013-03-05 20:37:43 +0200474 if (!rp->status)
475 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200476}
477
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300478static void hci_cc_read_local_features(struct hci_dev *hdev,
479 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200480{
481 struct hci_rp_read_local_features *rp = (void *) skb->data;
482
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300483 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200484
485 if (rp->status)
486 return;
487
488 memcpy(hdev->features, rp->features, 8);
489
490 /* Adjust default settings according to features
491 * supported by device. */
492
Johan Hedbergcad718e2013-04-17 15:00:51 +0300493 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200494 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
495
Johan Hedbergcad718e2013-04-17 15:00:51 +0300496 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200497 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
498
Johan Hedbergcad718e2013-04-17 15:00:51 +0300499 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200500 hdev->pkt_type |= (HCI_HV2);
501 hdev->esco_type |= (ESCO_HV2);
502 }
503
Johan Hedbergcad718e2013-04-17 15:00:51 +0300504 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200505 hdev->pkt_type |= (HCI_HV3);
506 hdev->esco_type |= (ESCO_HV3);
507 }
508
Andre Guedes45db810f2012-07-24 15:03:49 -0300509 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200510 hdev->esco_type |= (ESCO_EV3);
511
Johan Hedbergcad718e2013-04-17 15:00:51 +0300512 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200513 hdev->esco_type |= (ESCO_EV4);
514
Johan Hedbergcad718e2013-04-17 15:00:51 +0300515 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200516 hdev->esco_type |= (ESCO_EV5);
517
Johan Hedbergcad718e2013-04-17 15:00:51 +0300518 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100519 hdev->esco_type |= (ESCO_2EV3);
520
Johan Hedbergcad718e2013-04-17 15:00:51 +0300521 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100522 hdev->esco_type |= (ESCO_3EV3);
523
Johan Hedbergcad718e2013-04-17 15:00:51 +0300524 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100525 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
526
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200527 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
Johan Hedbergcad718e2013-04-17 15:00:51 +0300528 hdev->features[0][0], hdev->features[0][1],
529 hdev->features[0][2], hdev->features[0][3],
530 hdev->features[0][4], hdev->features[0][5],
531 hdev->features[0][6], hdev->features[0][7]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200532}
533
Andre Guedes971e3a42011-06-30 19:20:52 -0300534static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300535 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300536{
537 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
538
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300539 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300540
541 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200542 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300543
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300544 hdev->max_page = rp->max_page;
545
Johan Hedbergcad718e2013-04-17 15:00:51 +0300546 if (rp->page < HCI_MAX_PAGES)
547 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300548}
549
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200550static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300551 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200552{
553 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
554
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300555 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200556
Johan Hedberg42c6b122013-03-05 20:37:49 +0200557 if (!rp->status)
558 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200559}
560
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200561static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
562{
563 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
564
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300565 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200566
567 if (rp->status)
568 return;
569
570 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
571 hdev->sco_mtu = rp->sco_mtu;
572 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
573 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
574
575 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
576 hdev->sco_mtu = 64;
577 hdev->sco_pkts = 8;
578 }
579
580 hdev->acl_cnt = hdev->acl_pkts;
581 hdev->sco_cnt = hdev->sco_pkts;
582
Gustavo Padovan807deac2012-05-17 00:36:24 -0300583 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
584 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200585}
586
587static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
588{
589 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
590
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300591 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200592
593 if (!rp->status)
594 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200595}
596
Johan Hedbergf332ec62013-03-15 17:07:11 -0500597static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
598 struct sk_buff *skb)
599{
600 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
601
602 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
603
604 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
605 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
606 hdev->page_scan_window = __le16_to_cpu(rp->window);
607 }
608}
609
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500610static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
611 struct sk_buff *skb)
612{
613 u8 status = *((u8 *) skb->data);
614 struct hci_cp_write_page_scan_activity *sent;
615
616 BT_DBG("%s status 0x%2.2x", hdev->name, status);
617
618 if (status)
619 return;
620
621 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
622 if (!sent)
623 return;
624
625 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
626 hdev->page_scan_window = __le16_to_cpu(sent->window);
627}
628
Johan Hedbergf332ec62013-03-15 17:07:11 -0500629static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
630 struct sk_buff *skb)
631{
632 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
633
634 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
635
636 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
637 hdev->page_scan_type = rp->type;
638}
639
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500640static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
641 struct sk_buff *skb)
642{
643 u8 status = *((u8 *) skb->data);
644 u8 *type;
645
646 BT_DBG("%s status 0x%2.2x", hdev->name, status);
647
648 if (status)
649 return;
650
651 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
652 if (type)
653 hdev->page_scan_type = *type;
654}
655
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200656static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300657 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200658{
659 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
660
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300661 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200662
663 if (rp->status)
664 return;
665
666 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
667 hdev->block_len = __le16_to_cpu(rp->block_len);
668 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
669
670 hdev->block_cnt = hdev->num_blocks;
671
672 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300673 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200674}
675
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300676static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300677 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300678{
679 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
680
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300681 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300682
683 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300684 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300685
686 hdev->amp_status = rp->amp_status;
687 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
688 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
689 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
690 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
691 hdev->amp_type = rp->amp_type;
692 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
693 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
694 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
695 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
696
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300697a2mp_rsp:
698 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300699}
700
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300701static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
702 struct sk_buff *skb)
703{
704 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
705 struct amp_assoc *assoc = &hdev->loc_assoc;
706 size_t rem_len, frag_len;
707
708 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
709
710 if (rp->status)
711 goto a2mp_rsp;
712
713 frag_len = skb->len - sizeof(*rp);
714 rem_len = __le16_to_cpu(rp->rem_len);
715
716 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300717 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300718
719 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
720 assoc->offset += frag_len;
721
722 /* Read other fragments */
723 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
724
725 return;
726 }
727
728 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
729 assoc->len = assoc->offset + rem_len;
730 assoc->offset = 0;
731
732a2mp_rsp:
733 /* Send A2MP Rsp when all fragments are received */
734 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300735 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300736}
737
Johan Hedbergd5859e22011-01-25 01:19:58 +0200738static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300739 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200740{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700741 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200742
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300743 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200744
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700745 if (!rp->status)
746 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200747}
748
Johan Hedberg980e1a52011-01-22 06:10:07 +0200749static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
750{
751 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
752 struct hci_cp_pin_code_reply *cp;
753 struct hci_conn *conn;
754
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300755 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200756
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200757 hci_dev_lock(hdev);
758
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200759 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200760 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200761
Mikel Astizfa1bd912012-08-09 09:52:29 +0200762 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200763 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200764
765 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
766 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200767 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200768
769 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
770 if (conn)
771 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200772
773unlock:
774 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200775}
776
777static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
778{
779 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
780
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300781 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200782
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200783 hci_dev_lock(hdev);
784
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200785 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200786 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300787 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200788
789 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200790}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200791
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300792static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
793 struct sk_buff *skb)
794{
795 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
796
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300797 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300798
799 if (rp->status)
800 return;
801
802 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
803 hdev->le_pkts = rp->le_max_pkt;
804
805 hdev->le_cnt = hdev->le_pkts;
806
807 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300808}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200809
Johan Hedberg60e77322013-01-22 14:01:59 +0200810static void hci_cc_le_read_local_features(struct hci_dev *hdev,
811 struct sk_buff *skb)
812{
813 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
814
815 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
816
817 if (!rp->status)
818 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200819}
820
Johan Hedberg8fa19092012-10-19 20:57:49 +0300821static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
822 struct sk_buff *skb)
823{
824 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
825
826 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
827
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500828 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300829 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300830}
831
Johan Hedberga5c29682011-02-19 12:05:57 -0300832static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
833{
834 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
835
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300836 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300837
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200838 hci_dev_lock(hdev);
839
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200840 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300841 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
842 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200843
844 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300845}
846
847static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300848 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300849{
850 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
851
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300852 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300853
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200854 hci_dev_lock(hdev);
855
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200856 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200857 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300858 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200859
860 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300861}
862
Brian Gix1143d452011-11-23 08:28:34 -0800863static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
864{
865 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
866
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300867 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800868
869 hci_dev_lock(hdev);
870
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200871 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200872 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300873 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800874
875 hci_dev_unlock(hdev);
876}
877
878static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300879 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800880{
881 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
882
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300883 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800884
885 hci_dev_lock(hdev);
886
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200887 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800888 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300889 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800890
891 hci_dev_unlock(hdev);
892}
893
Szymon Jancc35938b2011-03-22 13:12:21 +0100894static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300895 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100896{
897 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
898
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300899 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100900
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200901 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200902 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100903 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200904 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100905}
906
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100907static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
908{
909 __u8 *sent, status = *((__u8 *) skb->data);
910
911 BT_DBG("%s status 0x%2.2x", hdev->name, status);
912
913 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
914 if (!sent)
915 return;
916
917 hci_dev_lock(hdev);
918
919 if (!status) {
920 if (*sent)
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200921 set_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100922 else
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200923 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100924 }
925
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500926 if (!test_bit(HCI_INIT, &hdev->flags)) {
927 struct hci_request req;
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100928
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500929 hci_req_init(&req, hdev);
930 hci_update_ad(&req);
931 hci_req_run(&req, NULL);
932 }
933
934 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100935}
936
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300937static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300938 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300939{
940 struct hci_cp_le_set_scan_enable *cp;
941 __u8 status = *((__u8 *) skb->data);
942
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300943 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300944
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300945 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
946 if (!cp)
947 return;
948
Andre Guedes3fd319b2013-04-30 15:29:36 -0300949 if (status)
950 return;
951
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200952 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -0300953 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300954 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200955 break;
956
Andre Guedes76a388b2013-04-04 20:21:02 -0300957 case LE_SCAN_DISABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300958 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200959 break;
960
961 default:
962 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
963 break;
Andre Guedes35815082011-05-26 16:23:53 -0300964 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300965}
966
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200967static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
968 struct sk_buff *skb)
969{
970 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
971
972 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
973
974 if (!rp->status)
975 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200976}
977
Johan Hedberg9b008c02013-01-22 14:02:01 +0200978static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
979 struct sk_buff *skb)
980{
981 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
982
983 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
984
985 if (!rp->status)
986 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +0200987}
988
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300989static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
990 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -0300991{
Johan Hedberg06199cf2012-02-22 16:37:11 +0200992 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -0300993 __u8 status = *((__u8 *) skb->data);
994
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300995 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -0300996
Johan Hedberg06199cf2012-02-22 16:37:11 +0200997 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +0200998 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -0300999 return;
1000
Johan Hedberg8f984df2012-02-28 01:07:22 +02001001 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001002 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001003 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001004 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1005 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001006 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001007 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001008 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001009 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001010
1011 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001012 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001013 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001014 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001015 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001016}
1017
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001018static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1019 struct sk_buff *skb)
1020{
1021 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1022
1023 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1024 hdev->name, rp->status, rp->phy_handle);
1025
1026 if (rp->status)
1027 return;
1028
1029 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1030}
1031
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001032static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001033{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001034 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001035
1036 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001037 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001038 return;
1039 }
1040
Andre Guedes89352e72011-11-04 14:16:53 -03001041 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001042}
1043
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001044static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001046 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001049 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001050
1051 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 if (!cp)
1053 return;
1054
1055 hci_dev_lock(hdev);
1056
1057 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1058
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001059 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060
1061 if (status) {
1062 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001063 if (status != 0x0c || conn->attempt > 2) {
1064 conn->state = BT_CLOSED;
1065 hci_proto_connect_cfm(conn, status);
1066 hci_conn_del(conn);
1067 } else
1068 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069 }
1070 } else {
1071 if (!conn) {
1072 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1073 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001074 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 conn->link_mode |= HCI_LM_MASTER;
1076 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001077 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 }
1079 }
1080
1081 hci_dev_unlock(hdev);
1082}
1083
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001084static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001086 struct hci_cp_add_sco *cp;
1087 struct hci_conn *acl, *sco;
1088 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001090 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001091
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001092 if (!status)
1093 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001095 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1096 if (!cp)
1097 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001099 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001101 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001102
1103 hci_dev_lock(hdev);
1104
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001105 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001106 if (acl) {
1107 sco = acl->link;
1108 if (sco) {
1109 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001110
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001111 hci_proto_connect_cfm(sco, status);
1112 hci_conn_del(sco);
1113 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001114 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001115
1116 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117}
1118
Marcel Holtmannf8558552008-07-14 20:13:49 +02001119static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1120{
1121 struct hci_cp_auth_requested *cp;
1122 struct hci_conn *conn;
1123
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001124 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001125
1126 if (!status)
1127 return;
1128
1129 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1130 if (!cp)
1131 return;
1132
1133 hci_dev_lock(hdev);
1134
1135 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1136 if (conn) {
1137 if (conn->state == BT_CONFIG) {
1138 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001139 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001140 }
1141 }
1142
1143 hci_dev_unlock(hdev);
1144}
1145
1146static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1147{
1148 struct hci_cp_set_conn_encrypt *cp;
1149 struct hci_conn *conn;
1150
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001151 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001152
1153 if (!status)
1154 return;
1155
1156 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1157 if (!cp)
1158 return;
1159
1160 hci_dev_lock(hdev);
1161
1162 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1163 if (conn) {
1164 if (conn->state == BT_CONFIG) {
1165 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001166 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001167 }
1168 }
1169
1170 hci_dev_unlock(hdev);
1171}
1172
Johan Hedberg127178d2010-11-18 22:22:29 +02001173static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001174 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001175{
Johan Hedberg392599b2010-11-18 22:22:28 +02001176 if (conn->state != BT_CONFIG || !conn->out)
1177 return 0;
1178
Johan Hedberg765c2a92011-01-19 12:06:52 +05301179 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001180 return 0;
1181
1182 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001183 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001184 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1185 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001186 return 0;
1187
Johan Hedberg392599b2010-11-18 22:22:28 +02001188 return 1;
1189}
1190
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001191static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001192 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001193{
1194 struct hci_cp_remote_name_req cp;
1195
1196 memset(&cp, 0, sizeof(cp));
1197
1198 bacpy(&cp.bdaddr, &e->data.bdaddr);
1199 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1200 cp.pscan_mode = e->data.pscan_mode;
1201 cp.clock_offset = e->data.clock_offset;
1202
1203 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1204}
1205
Johan Hedbergb644ba32012-01-17 21:48:47 +02001206static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001207{
1208 struct discovery_state *discov = &hdev->discovery;
1209 struct inquiry_entry *e;
1210
Johan Hedbergb644ba32012-01-17 21:48:47 +02001211 if (list_empty(&discov->resolve))
1212 return false;
1213
1214 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001215 if (!e)
1216 return false;
1217
Johan Hedbergb644ba32012-01-17 21:48:47 +02001218 if (hci_resolve_name(hdev, e) == 0) {
1219 e->name_state = NAME_PENDING;
1220 return true;
1221 }
1222
1223 return false;
1224}
1225
1226static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001227 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001228{
1229 struct discovery_state *discov = &hdev->discovery;
1230 struct inquiry_entry *e;
1231
1232 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001233 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1234 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001235
1236 if (discov->state == DISCOVERY_STOPPED)
1237 return;
1238
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001239 if (discov->state == DISCOVERY_STOPPING)
1240 goto discov_complete;
1241
1242 if (discov->state != DISCOVERY_RESOLVING)
1243 return;
1244
1245 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001246 /* If the device was not found in a list of found devices names of which
1247 * are pending. there is no need to continue resolving a next name as it
1248 * will be done upon receiving another Remote Name Request Complete
1249 * Event */
1250 if (!e)
1251 return;
1252
1253 list_del(&e->list);
1254 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001255 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001256 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1257 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001258 } else {
1259 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001260 }
1261
Johan Hedbergb644ba32012-01-17 21:48:47 +02001262 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001263 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001264
1265discov_complete:
1266 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1267}
1268
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001269static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1270{
Johan Hedberg127178d2010-11-18 22:22:29 +02001271 struct hci_cp_remote_name_req *cp;
1272 struct hci_conn *conn;
1273
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001274 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001275
1276 /* If successful wait for the name req complete event before
1277 * checking for the need to do authentication */
1278 if (!status)
1279 return;
1280
1281 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1282 if (!cp)
1283 return;
1284
1285 hci_dev_lock(hdev);
1286
1287 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001288
1289 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1290 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1291
Johan Hedberg79c6c702011-04-28 11:28:55 -07001292 if (!conn)
1293 goto unlock;
1294
1295 if (!hci_outgoing_auth_needed(hdev, conn))
1296 goto unlock;
1297
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001298 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001299 struct hci_cp_auth_requested auth_cp;
1300
1301 auth_cp.handle = __cpu_to_le16(conn->handle);
1302 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1303 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001304 }
1305
Johan Hedberg79c6c702011-04-28 11:28:55 -07001306unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001307 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001308}
1309
Marcel Holtmann769be972008-07-14 20:13:49 +02001310static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1311{
1312 struct hci_cp_read_remote_features *cp;
1313 struct hci_conn *conn;
1314
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001315 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001316
1317 if (!status)
1318 return;
1319
1320 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1321 if (!cp)
1322 return;
1323
1324 hci_dev_lock(hdev);
1325
1326 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1327 if (conn) {
1328 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001329 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001330 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001331 }
1332 }
1333
1334 hci_dev_unlock(hdev);
1335}
1336
1337static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1338{
1339 struct hci_cp_read_remote_ext_features *cp;
1340 struct hci_conn *conn;
1341
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001342 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001343
1344 if (!status)
1345 return;
1346
1347 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1348 if (!cp)
1349 return;
1350
1351 hci_dev_lock(hdev);
1352
1353 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1354 if (conn) {
1355 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001356 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001357 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001358 }
1359 }
1360
1361 hci_dev_unlock(hdev);
1362}
1363
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001364static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1365{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001366 struct hci_cp_setup_sync_conn *cp;
1367 struct hci_conn *acl, *sco;
1368 __u16 handle;
1369
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001370 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001371
1372 if (!status)
1373 return;
1374
1375 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1376 if (!cp)
1377 return;
1378
1379 handle = __le16_to_cpu(cp->handle);
1380
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001381 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001382
1383 hci_dev_lock(hdev);
1384
1385 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001386 if (acl) {
1387 sco = acl->link;
1388 if (sco) {
1389 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001390
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001391 hci_proto_connect_cfm(sco, status);
1392 hci_conn_del(sco);
1393 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001394 }
1395
1396 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001397}
1398
1399static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1400{
1401 struct hci_cp_sniff_mode *cp;
1402 struct hci_conn *conn;
1403
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001404 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001405
1406 if (!status)
1407 return;
1408
1409 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1410 if (!cp)
1411 return;
1412
1413 hci_dev_lock(hdev);
1414
1415 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001416 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001417 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001418
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001419 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001420 hci_sco_setup(conn, status);
1421 }
1422
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001423 hci_dev_unlock(hdev);
1424}
1425
1426static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1427{
1428 struct hci_cp_exit_sniff_mode *cp;
1429 struct hci_conn *conn;
1430
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001431 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001432
1433 if (!status)
1434 return;
1435
1436 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1437 if (!cp)
1438 return;
1439
1440 hci_dev_lock(hdev);
1441
1442 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001443 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001444 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001445
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001446 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001447 hci_sco_setup(conn, status);
1448 }
1449
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001450 hci_dev_unlock(hdev);
1451}
1452
Johan Hedberg88c3df12012-02-09 14:27:38 +02001453static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1454{
1455 struct hci_cp_disconnect *cp;
1456 struct hci_conn *conn;
1457
1458 if (!status)
1459 return;
1460
1461 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1462 if (!cp)
1463 return;
1464
1465 hci_dev_lock(hdev);
1466
1467 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1468 if (conn)
1469 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001470 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001471
1472 hci_dev_unlock(hdev);
1473}
1474
Ville Tervofcd89c02011-02-10 22:38:47 -03001475static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1476{
Ville Tervofcd89c02011-02-10 22:38:47 -03001477 struct hci_conn *conn;
1478
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001479 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Ville Tervofcd89c02011-02-10 22:38:47 -03001480
Ville Tervofcd89c02011-02-10 22:38:47 -03001481 if (status) {
Andre Guedesf00a06a2012-07-27 15:10:13 -03001482 hci_dev_lock(hdev);
Ville Tervofcd89c02011-02-10 22:38:47 -03001483
Andre Guedes0c95ab72012-07-27 15:10:14 -03001484 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001485 if (!conn) {
1486 hci_dev_unlock(hdev);
1487 return;
1488 }
1489
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001490 BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001491
1492 conn->state = BT_CLOSED;
Andre Guedes0c95ab72012-07-27 15:10:14 -03001493 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Andre Guedesf00a06a2012-07-27 15:10:13 -03001494 conn->dst_type, status);
1495 hci_proto_connect_cfm(conn, status);
1496 hci_conn_del(conn);
1497
1498 hci_dev_unlock(hdev);
1499 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001500}
1501
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001502static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1503{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001504 struct hci_cp_create_phy_link *cp;
1505
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001506 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001507
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001508 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1509 if (!cp)
1510 return;
1511
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001512 hci_dev_lock(hdev);
1513
1514 if (status) {
1515 struct hci_conn *hcon;
1516
1517 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1518 if (hcon)
1519 hci_conn_del(hcon);
1520 } else {
1521 amp_write_remote_assoc(hdev, cp->phy_handle);
1522 }
1523
1524 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001525}
1526
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001527static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1528{
1529 struct hci_cp_accept_phy_link *cp;
1530
1531 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1532
1533 if (status)
1534 return;
1535
1536 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1537 if (!cp)
1538 return;
1539
1540 amp_write_remote_assoc(hdev, cp->phy_handle);
1541}
1542
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001543static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001544{
1545 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001546 struct discovery_state *discov = &hdev->discovery;
1547 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001548
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001549 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001550
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001551 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001552
1553 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1554 return;
1555
Andre Guedes3e13fa12013-03-27 20:04:56 -03001556 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1557 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1558
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001559 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001560 return;
1561
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001562 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001563
Andre Guedes343f9352012-02-17 20:39:37 -03001564 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001565 goto unlock;
1566
1567 if (list_empty(&discov->resolve)) {
1568 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1569 goto unlock;
1570 }
1571
1572 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1573 if (e && hci_resolve_name(hdev, e) == 0) {
1574 e->name_state = NAME_PENDING;
1575 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1576 } else {
1577 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1578 }
1579
1580unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001581 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001582}
1583
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001584static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001586 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001587 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588 int num_rsp = *((__u8 *) skb->data);
1589
1590 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1591
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001592 if (!num_rsp)
1593 return;
1594
Andre Guedes1519cc12012-03-21 00:03:38 -03001595 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1596 return;
1597
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001599
Johan Hedberge17acd42011-03-30 23:57:16 +03001600 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001601 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001602
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603 bacpy(&data.bdaddr, &info->bdaddr);
1604 data.pscan_rep_mode = info->pscan_rep_mode;
1605 data.pscan_period_mode = info->pscan_period_mode;
1606 data.pscan_mode = info->pscan_mode;
1607 memcpy(data.dev_class, info->dev_class, 3);
1608 data.clock_offset = info->clock_offset;
1609 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001610 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001611
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001612 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001613 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001614 info->dev_class, 0, !name_known, ssp, NULL,
1615 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001617
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 hci_dev_unlock(hdev);
1619}
1620
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001621static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001623 struct hci_ev_conn_complete *ev = (void *) skb->data;
1624 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001626 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001627
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001629
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001630 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001631 if (!conn) {
1632 if (ev->link_type != SCO_LINK)
1633 goto unlock;
1634
1635 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1636 if (!conn)
1637 goto unlock;
1638
1639 conn->type = SCO_LINK;
1640 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001641
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001642 if (!ev->status) {
1643 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001644
1645 if (conn->type == ACL_LINK) {
1646 conn->state = BT_CONFIG;
1647 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001648
1649 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1650 !hci_find_link_key(hdev, &ev->bdaddr))
1651 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1652 else
1653 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001654 } else
1655 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001656
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001657 hci_conn_add_sysfs(conn);
1658
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001659 if (test_bit(HCI_AUTH, &hdev->flags))
1660 conn->link_mode |= HCI_LM_AUTH;
1661
1662 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1663 conn->link_mode |= HCI_LM_ENCRYPT;
1664
1665 /* Get remote features */
1666 if (conn->type == ACL_LINK) {
1667 struct hci_cp_read_remote_features cp;
1668 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001669 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001670 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001671 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001672
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001673 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001674 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001675 struct hci_cp_change_conn_ptype cp;
1676 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001677 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001678 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1679 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001680 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001681 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001682 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001683 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001684 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001685 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001686 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001687
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001688 if (conn->type == ACL_LINK)
1689 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001690
Marcel Holtmann769be972008-07-14 20:13:49 +02001691 if (ev->status) {
1692 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001693 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001694 } else if (ev->link_type != ACL_LINK)
1695 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001696
1697unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001699
1700 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701}
1702
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001703static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001705 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001707 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001709 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001710 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001712 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1713 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714
Szymon Janc138d22e2011-02-17 16:44:23 +01001715 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001716 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001718 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720
1721 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001722
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001723 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1724 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001725 memcpy(ie->data.dev_class, ev->dev_class, 3);
1726
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001727 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1728 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001730 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1731 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001732 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 hci_dev_unlock(hdev);
1734 return;
1735 }
1736 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001737
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001739
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 hci_dev_unlock(hdev);
1741
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001742 if (ev->link_type == ACL_LINK ||
1743 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001744 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001745 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001747 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001749 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1750 cp.role = 0x00; /* Become master */
1751 else
1752 cp.role = 0x01; /* Remain slave */
1753
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001754 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1755 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001756 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001757 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001758 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001759
1760 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001761 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001762
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001763 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1764 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1765 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001766 cp.content_format = cpu_to_le16(hdev->voice_setting);
1767 cp.retrans_effort = 0xff;
1768
1769 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001770 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001771 } else {
1772 conn->state = BT_CONNECT2;
1773 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001774 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 } else {
1776 /* Connection rejected */
1777 struct hci_cp_reject_conn_req cp;
1778
1779 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001780 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001781 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 }
1783}
1784
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001785static u8 hci_to_mgmt_reason(u8 err)
1786{
1787 switch (err) {
1788 case HCI_ERROR_CONNECTION_TIMEOUT:
1789 return MGMT_DEV_DISCONN_TIMEOUT;
1790 case HCI_ERROR_REMOTE_USER_TERM:
1791 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1792 case HCI_ERROR_REMOTE_POWER_OFF:
1793 return MGMT_DEV_DISCONN_REMOTE;
1794 case HCI_ERROR_LOCAL_HOST_TERM:
1795 return MGMT_DEV_DISCONN_LOCAL_HOST;
1796 default:
1797 return MGMT_DEV_DISCONN_UNKNOWN;
1798 }
1799}
1800
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001801static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001803 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001804 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001806 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 hci_dev_lock(hdev);
1809
Marcel Holtmann04837f62006-07-03 10:02:33 +02001810 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001811 if (!conn)
1812 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001813
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001814 if (ev->status == 0)
1815 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
Johan Hedbergb644ba32012-01-17 21:48:47 +02001817 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001818 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001819 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001820 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001821 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001822 } else {
1823 u8 reason = hci_to_mgmt_reason(ev->reason);
1824
Johan Hedbergafc747a2012-01-15 18:11:07 +02001825 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001826 conn->dst_type, reason);
1827 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001828 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001829
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001830 if (ev->status == 0) {
Johan Hedberg22102462013-10-05 12:01:06 +02001831 u8 type = conn->type;
1832
1833 if (type == ACL_LINK && conn->flush_key)
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301834 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001835 hci_proto_disconn_cfm(conn, ev->reason);
1836 hci_conn_del(conn);
Johan Hedberg22102462013-10-05 12:01:06 +02001837
1838 /* Re-enable advertising if necessary, since it might
1839 * have been disabled by the connection. From the
1840 * HCI_LE_Set_Advertise_Enable command description in
1841 * the core specification (v4.0):
1842 * "The Controller shall continue advertising until the Host
1843 * issues an LE_Set_Advertise_Enable command with
1844 * Advertising_Enable set to 0x00 (Advertising is disabled)
1845 * or until a connection is created or until the Advertising
1846 * is timed out due to Directed Advertising."
1847 */
1848 if (type == LE_LINK)
Marcel Holtmann5976e602013-10-06 04:08:14 -07001849 mgmt_reenable_advertising(hdev);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001850 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001851
1852unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 hci_dev_unlock(hdev);
1854}
1855
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001856static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001857{
1858 struct hci_ev_auth_complete *ev = (void *) skb->data;
1859 struct hci_conn *conn;
1860
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001861 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001862
1863 hci_dev_lock(hdev);
1864
1865 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001866 if (!conn)
1867 goto unlock;
1868
1869 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001870 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001871 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001872 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001873 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001874 conn->link_mode |= HCI_LM_AUTH;
1875 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001876 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001877 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001878 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001879 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001880 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001881
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001882 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1883 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001884
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001885 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001886 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001887 struct hci_cp_set_conn_encrypt cp;
1888 cp.handle = ev->handle;
1889 cp.encrypt = 0x01;
1890 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001891 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001892 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001893 conn->state = BT_CONNECTED;
1894 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001895 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001896 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001897 } else {
1898 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001899
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001900 hci_conn_hold(conn);
1901 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001902 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001903 }
1904
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001905 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001906 if (!ev->status) {
1907 struct hci_cp_set_conn_encrypt cp;
1908 cp.handle = ev->handle;
1909 cp.encrypt = 0x01;
1910 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001911 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001912 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001913 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001914 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001915 }
1916 }
1917
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001918unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001919 hci_dev_unlock(hdev);
1920}
1921
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001922static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001923{
Johan Hedberg127178d2010-11-18 22:22:29 +02001924 struct hci_ev_remote_name *ev = (void *) skb->data;
1925 struct hci_conn *conn;
1926
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001927 BT_DBG("%s", hdev->name);
1928
1929 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001930
1931 hci_dev_lock(hdev);
1932
1933 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001934
1935 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1936 goto check_auth;
1937
1938 if (ev->status == 0)
1939 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001940 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001941 else
1942 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1943
1944check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001945 if (!conn)
1946 goto unlock;
1947
1948 if (!hci_outgoing_auth_needed(hdev, conn))
1949 goto unlock;
1950
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001951 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001952 struct hci_cp_auth_requested cp;
1953 cp.handle = __cpu_to_le16(conn->handle);
1954 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1955 }
1956
Johan Hedberg79c6c702011-04-28 11:28:55 -07001957unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001958 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001959}
1960
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001961static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001962{
1963 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1964 struct hci_conn *conn;
1965
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001966 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001967
1968 hci_dev_lock(hdev);
1969
1970 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1971 if (conn) {
1972 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001973 if (ev->encrypt) {
1974 /* Encryption implies authentication */
1975 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001976 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001977 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001978 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001979 conn->link_mode &= ~HCI_LM_ENCRYPT;
1980 }
1981
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001982 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001983
Gustavo Padovana7d77232012-05-13 03:20:07 -03001984 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03001985 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02001986 hci_conn_drop(conn);
Gustavo Padovana7d77232012-05-13 03:20:07 -03001987 goto unlock;
1988 }
1989
Marcel Holtmannf8558552008-07-14 20:13:49 +02001990 if (conn->state == BT_CONFIG) {
1991 if (!ev->status)
1992 conn->state = BT_CONNECTED;
1993
1994 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001995 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001996 } else
1997 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001998 }
1999
Gustavo Padovana7d77232012-05-13 03:20:07 -03002000unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002001 hci_dev_unlock(hdev);
2002}
2003
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002004static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2005 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002006{
2007 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2008 struct hci_conn *conn;
2009
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002010 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002011
2012 hci_dev_lock(hdev);
2013
2014 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2015 if (conn) {
2016 if (!ev->status)
2017 conn->link_mode |= HCI_LM_SECURE;
2018
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002019 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002020
2021 hci_key_change_cfm(conn, ev->status);
2022 }
2023
2024 hci_dev_unlock(hdev);
2025}
2026
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002027static void hci_remote_features_evt(struct hci_dev *hdev,
2028 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002029{
2030 struct hci_ev_remote_features *ev = (void *) skb->data;
2031 struct hci_conn *conn;
2032
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002033 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002034
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002035 hci_dev_lock(hdev);
2036
2037 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002038 if (!conn)
2039 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002040
Johan Hedbergccd556f2010-11-10 17:11:51 +02002041 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002042 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002043
2044 if (conn->state != BT_CONFIG)
2045 goto unlock;
2046
2047 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2048 struct hci_cp_read_remote_ext_features cp;
2049 cp.handle = ev->handle;
2050 cp.page = 0x01;
2051 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002052 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002053 goto unlock;
2054 }
2055
Johan Hedberg671267b2012-05-12 16:11:50 -03002056 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002057 struct hci_cp_remote_name_req cp;
2058 memset(&cp, 0, sizeof(cp));
2059 bacpy(&cp.bdaddr, &conn->dst);
2060 cp.pscan_rep_mode = 0x02;
2061 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002062 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2063 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002064 conn->dst_type, 0, NULL, 0,
2065 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002066
Johan Hedberg127178d2010-11-18 22:22:29 +02002067 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002068 conn->state = BT_CONNECTED;
2069 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002070 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002071 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002072
Johan Hedbergccd556f2010-11-10 17:11:51 +02002073unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002074 hci_dev_unlock(hdev);
2075}
2076
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002077static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002078{
2079 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002080 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002081 __u16 opcode;
2082
2083 skb_pull(skb, sizeof(*ev));
2084
2085 opcode = __le16_to_cpu(ev->opcode);
2086
2087 switch (opcode) {
2088 case HCI_OP_INQUIRY_CANCEL:
2089 hci_cc_inquiry_cancel(hdev, skb);
2090 break;
2091
Andre Guedes4d934832012-03-21 00:03:35 -03002092 case HCI_OP_PERIODIC_INQ:
2093 hci_cc_periodic_inq(hdev, skb);
2094 break;
2095
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002096 case HCI_OP_EXIT_PERIODIC_INQ:
2097 hci_cc_exit_periodic_inq(hdev, skb);
2098 break;
2099
2100 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2101 hci_cc_remote_name_req_cancel(hdev, skb);
2102 break;
2103
2104 case HCI_OP_ROLE_DISCOVERY:
2105 hci_cc_role_discovery(hdev, skb);
2106 break;
2107
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002108 case HCI_OP_READ_LINK_POLICY:
2109 hci_cc_read_link_policy(hdev, skb);
2110 break;
2111
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002112 case HCI_OP_WRITE_LINK_POLICY:
2113 hci_cc_write_link_policy(hdev, skb);
2114 break;
2115
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002116 case HCI_OP_READ_DEF_LINK_POLICY:
2117 hci_cc_read_def_link_policy(hdev, skb);
2118 break;
2119
2120 case HCI_OP_WRITE_DEF_LINK_POLICY:
2121 hci_cc_write_def_link_policy(hdev, skb);
2122 break;
2123
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002124 case HCI_OP_RESET:
2125 hci_cc_reset(hdev, skb);
2126 break;
2127
2128 case HCI_OP_WRITE_LOCAL_NAME:
2129 hci_cc_write_local_name(hdev, skb);
2130 break;
2131
2132 case HCI_OP_READ_LOCAL_NAME:
2133 hci_cc_read_local_name(hdev, skb);
2134 break;
2135
2136 case HCI_OP_WRITE_AUTH_ENABLE:
2137 hci_cc_write_auth_enable(hdev, skb);
2138 break;
2139
2140 case HCI_OP_WRITE_ENCRYPT_MODE:
2141 hci_cc_write_encrypt_mode(hdev, skb);
2142 break;
2143
2144 case HCI_OP_WRITE_SCAN_ENABLE:
2145 hci_cc_write_scan_enable(hdev, skb);
2146 break;
2147
2148 case HCI_OP_READ_CLASS_OF_DEV:
2149 hci_cc_read_class_of_dev(hdev, skb);
2150 break;
2151
2152 case HCI_OP_WRITE_CLASS_OF_DEV:
2153 hci_cc_write_class_of_dev(hdev, skb);
2154 break;
2155
2156 case HCI_OP_READ_VOICE_SETTING:
2157 hci_cc_read_voice_setting(hdev, skb);
2158 break;
2159
2160 case HCI_OP_WRITE_VOICE_SETTING:
2161 hci_cc_write_voice_setting(hdev, skb);
2162 break;
2163
Marcel Holtmann333140b2008-07-14 20:13:48 +02002164 case HCI_OP_WRITE_SSP_MODE:
2165 hci_cc_write_ssp_mode(hdev, skb);
2166 break;
2167
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002168 case HCI_OP_READ_LOCAL_VERSION:
2169 hci_cc_read_local_version(hdev, skb);
2170 break;
2171
2172 case HCI_OP_READ_LOCAL_COMMANDS:
2173 hci_cc_read_local_commands(hdev, skb);
2174 break;
2175
2176 case HCI_OP_READ_LOCAL_FEATURES:
2177 hci_cc_read_local_features(hdev, skb);
2178 break;
2179
Andre Guedes971e3a42011-06-30 19:20:52 -03002180 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2181 hci_cc_read_local_ext_features(hdev, skb);
2182 break;
2183
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002184 case HCI_OP_READ_BUFFER_SIZE:
2185 hci_cc_read_buffer_size(hdev, skb);
2186 break;
2187
2188 case HCI_OP_READ_BD_ADDR:
2189 hci_cc_read_bd_addr(hdev, skb);
2190 break;
2191
Johan Hedbergf332ec62013-03-15 17:07:11 -05002192 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2193 hci_cc_read_page_scan_activity(hdev, skb);
2194 break;
2195
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002196 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2197 hci_cc_write_page_scan_activity(hdev, skb);
2198 break;
2199
Johan Hedbergf332ec62013-03-15 17:07:11 -05002200 case HCI_OP_READ_PAGE_SCAN_TYPE:
2201 hci_cc_read_page_scan_type(hdev, skb);
2202 break;
2203
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002204 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2205 hci_cc_write_page_scan_type(hdev, skb);
2206 break;
2207
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002208 case HCI_OP_READ_DATA_BLOCK_SIZE:
2209 hci_cc_read_data_block_size(hdev, skb);
2210 break;
2211
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002212 case HCI_OP_READ_FLOW_CONTROL_MODE:
2213 hci_cc_read_flow_control_mode(hdev, skb);
2214 break;
2215
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002216 case HCI_OP_READ_LOCAL_AMP_INFO:
2217 hci_cc_read_local_amp_info(hdev, skb);
2218 break;
2219
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002220 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2221 hci_cc_read_local_amp_assoc(hdev, skb);
2222 break;
2223
Johan Hedbergd5859e22011-01-25 01:19:58 +02002224 case HCI_OP_READ_INQ_RSP_TX_POWER:
2225 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2226 break;
2227
Johan Hedberg980e1a52011-01-22 06:10:07 +02002228 case HCI_OP_PIN_CODE_REPLY:
2229 hci_cc_pin_code_reply(hdev, skb);
2230 break;
2231
2232 case HCI_OP_PIN_CODE_NEG_REPLY:
2233 hci_cc_pin_code_neg_reply(hdev, skb);
2234 break;
2235
Szymon Jancc35938b2011-03-22 13:12:21 +01002236 case HCI_OP_READ_LOCAL_OOB_DATA:
2237 hci_cc_read_local_oob_data_reply(hdev, skb);
2238 break;
2239
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002240 case HCI_OP_LE_READ_BUFFER_SIZE:
2241 hci_cc_le_read_buffer_size(hdev, skb);
2242 break;
2243
Johan Hedberg60e77322013-01-22 14:01:59 +02002244 case HCI_OP_LE_READ_LOCAL_FEATURES:
2245 hci_cc_le_read_local_features(hdev, skb);
2246 break;
2247
Johan Hedberg8fa19092012-10-19 20:57:49 +03002248 case HCI_OP_LE_READ_ADV_TX_POWER:
2249 hci_cc_le_read_adv_tx_power(hdev, skb);
2250 break;
2251
Johan Hedberga5c29682011-02-19 12:05:57 -03002252 case HCI_OP_USER_CONFIRM_REPLY:
2253 hci_cc_user_confirm_reply(hdev, skb);
2254 break;
2255
2256 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2257 hci_cc_user_confirm_neg_reply(hdev, skb);
2258 break;
2259
Brian Gix1143d452011-11-23 08:28:34 -08002260 case HCI_OP_USER_PASSKEY_REPLY:
2261 hci_cc_user_passkey_reply(hdev, skb);
2262 break;
2263
2264 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2265 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002266 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002267
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002268 case HCI_OP_LE_SET_ADV_ENABLE:
2269 hci_cc_le_set_adv_enable(hdev, skb);
2270 break;
2271
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002272 case HCI_OP_LE_SET_SCAN_ENABLE:
2273 hci_cc_le_set_scan_enable(hdev, skb);
2274 break;
2275
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002276 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2277 hci_cc_le_read_white_list_size(hdev, skb);
2278 break;
2279
Johan Hedberg9b008c02013-01-22 14:02:01 +02002280 case HCI_OP_LE_READ_SUPPORTED_STATES:
2281 hci_cc_le_read_supported_states(hdev, skb);
2282 break;
2283
Andre Guedesf9b49302011-06-30 19:20:53 -03002284 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2285 hci_cc_write_le_host_supported(hdev, skb);
2286 break;
2287
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002288 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2289 hci_cc_write_remote_amp_assoc(hdev, skb);
2290 break;
2291
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002292 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002293 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002294 break;
2295 }
2296
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002297 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002298 del_timer(&hdev->cmd_timer);
2299
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002300 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002301
Szymon Jancdbccd792012-12-11 08:51:19 +01002302 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002303 atomic_set(&hdev->cmd_cnt, 1);
2304 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002305 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002306 }
2307}
2308
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002309static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002310{
2311 struct hci_ev_cmd_status *ev = (void *) skb->data;
2312 __u16 opcode;
2313
2314 skb_pull(skb, sizeof(*ev));
2315
2316 opcode = __le16_to_cpu(ev->opcode);
2317
2318 switch (opcode) {
2319 case HCI_OP_INQUIRY:
2320 hci_cs_inquiry(hdev, ev->status);
2321 break;
2322
2323 case HCI_OP_CREATE_CONN:
2324 hci_cs_create_conn(hdev, ev->status);
2325 break;
2326
2327 case HCI_OP_ADD_SCO:
2328 hci_cs_add_sco(hdev, ev->status);
2329 break;
2330
Marcel Holtmannf8558552008-07-14 20:13:49 +02002331 case HCI_OP_AUTH_REQUESTED:
2332 hci_cs_auth_requested(hdev, ev->status);
2333 break;
2334
2335 case HCI_OP_SET_CONN_ENCRYPT:
2336 hci_cs_set_conn_encrypt(hdev, ev->status);
2337 break;
2338
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002339 case HCI_OP_REMOTE_NAME_REQ:
2340 hci_cs_remote_name_req(hdev, ev->status);
2341 break;
2342
Marcel Holtmann769be972008-07-14 20:13:49 +02002343 case HCI_OP_READ_REMOTE_FEATURES:
2344 hci_cs_read_remote_features(hdev, ev->status);
2345 break;
2346
2347 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2348 hci_cs_read_remote_ext_features(hdev, ev->status);
2349 break;
2350
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002351 case HCI_OP_SETUP_SYNC_CONN:
2352 hci_cs_setup_sync_conn(hdev, ev->status);
2353 break;
2354
2355 case HCI_OP_SNIFF_MODE:
2356 hci_cs_sniff_mode(hdev, ev->status);
2357 break;
2358
2359 case HCI_OP_EXIT_SNIFF_MODE:
2360 hci_cs_exit_sniff_mode(hdev, ev->status);
2361 break;
2362
Johan Hedberg8962ee72011-01-20 12:40:27 +02002363 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002364 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002365 break;
2366
Ville Tervofcd89c02011-02-10 22:38:47 -03002367 case HCI_OP_LE_CREATE_CONN:
2368 hci_cs_le_create_conn(hdev, ev->status);
2369 break;
2370
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002371 case HCI_OP_CREATE_PHY_LINK:
2372 hci_cs_create_phylink(hdev, ev->status);
2373 break;
2374
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002375 case HCI_OP_ACCEPT_PHY_LINK:
2376 hci_cs_accept_phylink(hdev, ev->status);
2377 break;
2378
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002379 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002380 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002381 break;
2382 }
2383
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002384 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002385 del_timer(&hdev->cmd_timer);
2386
Johan Hedberg02350a72013-04-03 21:50:29 +03002387 if (ev->status ||
2388 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2389 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002390
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002391 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002392 atomic_set(&hdev->cmd_cnt, 1);
2393 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002394 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002395 }
2396}
2397
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002398static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002399{
2400 struct hci_ev_role_change *ev = (void *) skb->data;
2401 struct hci_conn *conn;
2402
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002403 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002404
2405 hci_dev_lock(hdev);
2406
2407 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2408 if (conn) {
2409 if (!ev->status) {
2410 if (ev->role)
2411 conn->link_mode &= ~HCI_LM_MASTER;
2412 else
2413 conn->link_mode |= HCI_LM_MASTER;
2414 }
2415
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002416 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002417
2418 hci_role_switch_cfm(conn, ev->status, ev->role);
2419 }
2420
2421 hci_dev_unlock(hdev);
2422}
2423
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002424static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002425{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002426 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427 int i;
2428
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002429 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2430 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2431 return;
2432 }
2433
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002434 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002435 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002436 BT_DBG("%s bad parameters", hdev->name);
2437 return;
2438 }
2439
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002440 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2441
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002442 for (i = 0; i < ev->num_hndl; i++) {
2443 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002444 struct hci_conn *conn;
2445 __u16 handle, count;
2446
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002447 handle = __le16_to_cpu(info->handle);
2448 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449
2450 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002451 if (!conn)
2452 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002453
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002454 conn->sent -= count;
2455
2456 switch (conn->type) {
2457 case ACL_LINK:
2458 hdev->acl_cnt += count;
2459 if (hdev->acl_cnt > hdev->acl_pkts)
2460 hdev->acl_cnt = hdev->acl_pkts;
2461 break;
2462
2463 case LE_LINK:
2464 if (hdev->le_pkts) {
2465 hdev->le_cnt += count;
2466 if (hdev->le_cnt > hdev->le_pkts)
2467 hdev->le_cnt = hdev->le_pkts;
2468 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002469 hdev->acl_cnt += count;
2470 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002471 hdev->acl_cnt = hdev->acl_pkts;
2472 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002473 break;
2474
2475 case SCO_LINK:
2476 hdev->sco_cnt += count;
2477 if (hdev->sco_cnt > hdev->sco_pkts)
2478 hdev->sco_cnt = hdev->sco_pkts;
2479 break;
2480
2481 default:
2482 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2483 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002484 }
2485 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002486
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002487 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002488}
2489
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002490static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2491 __u16 handle)
2492{
2493 struct hci_chan *chan;
2494
2495 switch (hdev->dev_type) {
2496 case HCI_BREDR:
2497 return hci_conn_hash_lookup_handle(hdev, handle);
2498 case HCI_AMP:
2499 chan = hci_chan_lookup_handle(hdev, handle);
2500 if (chan)
2501 return chan->conn;
2502 break;
2503 default:
2504 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2505 break;
2506 }
2507
2508 return NULL;
2509}
2510
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002511static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002512{
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) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002522 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002523 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,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002528 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002529
2530 for (i = 0; i < ev->num_hndl; i++) {
2531 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002532 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002533 __u16 handle, block_count;
2534
2535 handle = __le16_to_cpu(info->handle);
2536 block_count = __le16_to_cpu(info->blocks);
2537
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002538 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002539 if (!conn)
2540 continue;
2541
2542 conn->sent -= block_count;
2543
2544 switch (conn->type) {
2545 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002546 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002547 hdev->block_cnt += block_count;
2548 if (hdev->block_cnt > hdev->num_blocks)
2549 hdev->block_cnt = hdev->num_blocks;
2550 break;
2551
2552 default:
2553 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2554 break;
2555 }
2556 }
2557
2558 queue_work(hdev->workqueue, &hdev->tx_work);
2559}
2560
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002561static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002563 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002564 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002566 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567
2568 hci_dev_lock(hdev);
2569
Marcel Holtmann04837f62006-07-03 10:02:33 +02002570 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2571 if (conn) {
2572 conn->mode = ev->mode;
2573 conn->interval = __le16_to_cpu(ev->interval);
2574
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002575 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2576 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002577 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002578 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002579 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002580 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002581 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002582
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002583 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002584 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002585 }
2586
2587 hci_dev_unlock(hdev);
2588}
2589
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002590static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002591{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002592 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2593 struct hci_conn *conn;
2594
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002595 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002596
2597 hci_dev_lock(hdev);
2598
2599 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002600 if (!conn)
2601 goto unlock;
2602
2603 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002604 hci_conn_hold(conn);
2605 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002606 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002607 }
2608
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002609 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002610 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002611 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002612 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002613 u8 secure;
2614
2615 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2616 secure = 1;
2617 else
2618 secure = 0;
2619
Johan Hedberg744cf192011-11-08 20:40:14 +02002620 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002621 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002622
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002623unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002624 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002625}
2626
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002627static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002629 struct hci_ev_link_key_req *ev = (void *) skb->data;
2630 struct hci_cp_link_key_reply cp;
2631 struct hci_conn *conn;
2632 struct link_key *key;
2633
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002634 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002635
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002636 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002637 return;
2638
2639 hci_dev_lock(hdev);
2640
2641 key = hci_find_link_key(hdev, &ev->bdaddr);
2642 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002643 BT_DBG("%s link key not found for %pMR", hdev->name,
2644 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002645 goto not_found;
2646 }
2647
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002648 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2649 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002650
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002651 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002652 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002653 BT_DBG("%s ignoring debug key", hdev->name);
2654 goto not_found;
2655 }
2656
2657 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002658 if (conn) {
2659 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002660 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002661 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2662 goto not_found;
2663 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002664
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002665 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002666 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002667 BT_DBG("%s ignoring key unauthenticated for high security",
2668 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002669 goto not_found;
2670 }
2671
2672 conn->key_type = key->type;
2673 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002674 }
2675
2676 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002677 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002678
2679 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2680
2681 hci_dev_unlock(hdev);
2682
2683 return;
2684
2685not_found:
2686 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2687 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688}
2689
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002690static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002692 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2693 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002694 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002695
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002696 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002697
2698 hci_dev_lock(hdev);
2699
2700 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2701 if (conn) {
2702 hci_conn_hold(conn);
2703 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002704 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002705
2706 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2707 conn->key_type = ev->key_type;
2708
David Herrmann76a68ba2013-04-06 20:28:37 +02002709 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002710 }
2711
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002712 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002713 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002714 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002715
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002716 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002717}
2718
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002719static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002720{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002721 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002722 struct hci_conn *conn;
2723
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002724 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002725
2726 hci_dev_lock(hdev);
2727
2728 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002729 if (conn && !ev->status) {
2730 struct inquiry_entry *ie;
2731
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002732 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2733 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002734 ie->data.clock_offset = ev->clock_offset;
2735 ie->timestamp = jiffies;
2736 }
2737 }
2738
2739 hci_dev_unlock(hdev);
2740}
2741
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002742static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002743{
2744 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2745 struct hci_conn *conn;
2746
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002747 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002748
2749 hci_dev_lock(hdev);
2750
2751 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2752 if (conn && !ev->status)
2753 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2754
2755 hci_dev_unlock(hdev);
2756}
2757
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002758static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002759{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002760 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002761 struct inquiry_entry *ie;
2762
2763 BT_DBG("%s", hdev->name);
2764
2765 hci_dev_lock(hdev);
2766
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002767 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2768 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002769 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2770 ie->timestamp = jiffies;
2771 }
2772
2773 hci_dev_unlock(hdev);
2774}
2775
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002776static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2777 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002778{
2779 struct inquiry_data data;
2780 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002781 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002782
2783 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2784
2785 if (!num_rsp)
2786 return;
2787
Andre Guedes1519cc12012-03-21 00:03:38 -03002788 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2789 return;
2790
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002791 hci_dev_lock(hdev);
2792
2793 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002794 struct inquiry_info_with_rssi_and_pscan_mode *info;
2795 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002796
Johan Hedberge17acd42011-03-30 23:57:16 +03002797 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002798 bacpy(&data.bdaddr, &info->bdaddr);
2799 data.pscan_rep_mode = info->pscan_rep_mode;
2800 data.pscan_period_mode = info->pscan_period_mode;
2801 data.pscan_mode = info->pscan_mode;
2802 memcpy(data.dev_class, info->dev_class, 3);
2803 data.clock_offset = info->clock_offset;
2804 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002805 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002806
2807 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002808 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002809 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002810 info->dev_class, info->rssi,
2811 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002812 }
2813 } else {
2814 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2815
Johan Hedberge17acd42011-03-30 23:57:16 +03002816 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002817 bacpy(&data.bdaddr, &info->bdaddr);
2818 data.pscan_rep_mode = info->pscan_rep_mode;
2819 data.pscan_period_mode = info->pscan_period_mode;
2820 data.pscan_mode = 0x00;
2821 memcpy(data.dev_class, info->dev_class, 3);
2822 data.clock_offset = info->clock_offset;
2823 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002824 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002825 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002826 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002827 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002828 info->dev_class, info->rssi,
2829 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002830 }
2831 }
2832
2833 hci_dev_unlock(hdev);
2834}
2835
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002836static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2837 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002838{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002839 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2840 struct hci_conn *conn;
2841
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002842 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002843
Marcel Holtmann41a96212008-07-14 20:13:48 +02002844 hci_dev_lock(hdev);
2845
2846 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002847 if (!conn)
2848 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002849
Johan Hedbergcad718e2013-04-17 15:00:51 +03002850 if (ev->page < HCI_MAX_PAGES)
2851 memcpy(conn->features[ev->page], ev->features, 8);
2852
Johan Hedbergccd556f2010-11-10 17:11:51 +02002853 if (!ev->status && ev->page == 0x01) {
2854 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002855
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002856 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2857 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002858 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002859
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302860 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002861 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302862 } else {
2863 /* It is mandatory by the Bluetooth specification that
2864 * Extended Inquiry Results are only used when Secure
2865 * Simple Pairing is enabled, but some devices violate
2866 * this.
2867 *
2868 * To make these devices work, the internal SSP
2869 * enabled flag needs to be cleared if the remote host
2870 * features do not indicate SSP support */
2871 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2872 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002873 }
2874
Johan Hedbergccd556f2010-11-10 17:11:51 +02002875 if (conn->state != BT_CONFIG)
2876 goto unlock;
2877
Johan Hedberg671267b2012-05-12 16:11:50 -03002878 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002879 struct hci_cp_remote_name_req cp;
2880 memset(&cp, 0, sizeof(cp));
2881 bacpy(&cp.bdaddr, &conn->dst);
2882 cp.pscan_rep_mode = 0x02;
2883 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002884 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2885 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002886 conn->dst_type, 0, NULL, 0,
2887 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002888
Johan Hedberg127178d2010-11-18 22:22:29 +02002889 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002890 conn->state = BT_CONNECTED;
2891 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002892 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002893 }
2894
2895unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002896 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002897}
2898
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002899static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2900 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002901{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002902 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2903 struct hci_conn *conn;
2904
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002905 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002906
2907 hci_dev_lock(hdev);
2908
2909 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002910 if (!conn) {
2911 if (ev->link_type == ESCO_LINK)
2912 goto unlock;
2913
2914 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2915 if (!conn)
2916 goto unlock;
2917
2918 conn->type = SCO_LINK;
2919 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002920
Marcel Holtmann732547f2009-04-19 19:14:14 +02002921 switch (ev->status) {
2922 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002923 conn->handle = __le16_to_cpu(ev->handle);
2924 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002925
2926 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002927 break;
2928
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02002929 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05002930 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002931 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002932 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002933 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002934 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02002935 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2936 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002937 if (hci_setup_sync(conn, conn->link->handle))
2938 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002939 }
2940 /* fall through */
2941
2942 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002943 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002944 break;
2945 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002946
2947 hci_proto_connect_cfm(conn, ev->status);
2948 if (ev->status)
2949 hci_conn_del(conn);
2950
2951unlock:
2952 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002953}
2954
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002955static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2956 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002957{
2958 struct inquiry_data data;
2959 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2960 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302961 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002962
2963 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2964
2965 if (!num_rsp)
2966 return;
2967
Andre Guedes1519cc12012-03-21 00:03:38 -03002968 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2969 return;
2970
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002971 hci_dev_lock(hdev);
2972
Johan Hedberge17acd42011-03-30 23:57:16 +03002973 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002974 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002975
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002976 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002977 data.pscan_rep_mode = info->pscan_rep_mode;
2978 data.pscan_period_mode = info->pscan_period_mode;
2979 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002980 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002981 data.clock_offset = info->clock_offset;
2982 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002983 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002984
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002985 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002986 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002987 sizeof(info->data),
2988 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002989 else
2990 name_known = true;
2991
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002992 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002993 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302994 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02002995 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002996 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302997 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002998 }
2999
3000 hci_dev_unlock(hdev);
3001}
3002
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003003static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3004 struct sk_buff *skb)
3005{
3006 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3007 struct hci_conn *conn;
3008
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003009 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003010 __le16_to_cpu(ev->handle));
3011
3012 hci_dev_lock(hdev);
3013
3014 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3015 if (!conn)
3016 goto unlock;
3017
3018 if (!ev->status)
3019 conn->sec_level = conn->pending_sec_level;
3020
3021 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3022
3023 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003024 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003025 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003026 goto unlock;
3027 }
3028
3029 if (conn->state == BT_CONFIG) {
3030 if (!ev->status)
3031 conn->state = BT_CONNECTED;
3032
3033 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003034 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003035 } else {
3036 hci_auth_cfm(conn, ev->status);
3037
3038 hci_conn_hold(conn);
3039 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003040 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003041 }
3042
3043unlock:
3044 hci_dev_unlock(hdev);
3045}
3046
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003047static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003048{
3049 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003050 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3051 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003052 /* If both remote and local IO capabilities allow MITM
3053 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003054 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3055 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3056 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003057 else
Mikel Astizacabae92013-06-28 10:56:28 +02003058 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003059 }
3060
3061 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003062 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3063 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003064 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003065
3066 return conn->auth_type;
3067}
3068
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003069static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003070{
3071 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3072 struct hci_conn *conn;
3073
3074 BT_DBG("%s", hdev->name);
3075
3076 hci_dev_lock(hdev);
3077
3078 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003079 if (!conn)
3080 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003081
Johan Hedberg03b555e2011-01-04 15:40:05 +02003082 hci_conn_hold(conn);
3083
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003084 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003085 goto unlock;
3086
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003087 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003088 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003089 struct hci_cp_io_capability_reply cp;
3090
3091 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303092 /* Change the IO capability from KeyboardDisplay
3093 * to DisplayYesNo as it is not supported by BT spec. */
3094 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003095 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003096 conn->auth_type = hci_get_auth_req(conn);
3097 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003098
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003099 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3100 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003101 cp.oob_data = 0x01;
3102 else
3103 cp.oob_data = 0x00;
3104
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003105 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003106 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003107 } else {
3108 struct hci_cp_io_capability_neg_reply cp;
3109
3110 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003111 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003112
3113 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003114 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003115 }
3116
3117unlock:
3118 hci_dev_unlock(hdev);
3119}
3120
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003121static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003122{
3123 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3124 struct hci_conn *conn;
3125
3126 BT_DBG("%s", hdev->name);
3127
3128 hci_dev_lock(hdev);
3129
3130 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3131 if (!conn)
3132 goto unlock;
3133
Johan Hedberg03b555e2011-01-04 15:40:05 +02003134 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003135 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003136 if (ev->oob_data)
3137 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003138
3139unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003140 hci_dev_unlock(hdev);
3141}
3142
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003143static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3144 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003145{
3146 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003147 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003148 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003149
3150 BT_DBG("%s", hdev->name);
3151
3152 hci_dev_lock(hdev);
3153
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003154 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003155 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003156
Johan Hedberg7a828902011-04-28 11:28:53 -07003157 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3158 if (!conn)
3159 goto unlock;
3160
3161 loc_mitm = (conn->auth_type & 0x01);
3162 rem_mitm = (conn->remote_auth & 0x01);
3163
3164 /* If we require MITM but the remote device can't provide that
3165 * (it has NoInputNoOutput) then reject the confirmation
3166 * request. The only exception is when we're dedicated bonding
3167 * initiators (connect_cfm_cb set) since then we always have the MITM
3168 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003169 if (!conn->connect_cfm_cb && loc_mitm &&
3170 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003171 BT_DBG("Rejecting request: remote device can't provide MITM");
3172 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003173 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003174 goto unlock;
3175 }
3176
3177 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003178 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3179 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003180
3181 /* If we're not the initiators request authorization to
3182 * proceed from user space (mgmt_user_confirm with
3183 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003184 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003185 BT_DBG("Confirming auto-accept as acceptor");
3186 confirm_hint = 1;
3187 goto confirm;
3188 }
3189
Johan Hedberg9f616562011-04-28 11:28:54 -07003190 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003191 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003192
3193 if (hdev->auto_accept_delay > 0) {
3194 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3195 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3196 goto unlock;
3197 }
3198
Johan Hedberg7a828902011-04-28 11:28:53 -07003199 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003200 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003201 goto unlock;
3202 }
3203
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003204confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003205 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003206 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003207
3208unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003209 hci_dev_unlock(hdev);
3210}
3211
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003212static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3213 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003214{
3215 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3216
3217 BT_DBG("%s", hdev->name);
3218
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003219 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003220 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003221}
3222
Johan Hedberg92a25252012-09-06 18:39:26 +03003223static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3224 struct sk_buff *skb)
3225{
3226 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3227 struct hci_conn *conn;
3228
3229 BT_DBG("%s", hdev->name);
3230
3231 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3232 if (!conn)
3233 return;
3234
3235 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3236 conn->passkey_entered = 0;
3237
3238 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3239 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3240 conn->dst_type, conn->passkey_notify,
3241 conn->passkey_entered);
3242}
3243
3244static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3245{
3246 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3247 struct hci_conn *conn;
3248
3249 BT_DBG("%s", hdev->name);
3250
3251 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3252 if (!conn)
3253 return;
3254
3255 switch (ev->type) {
3256 case HCI_KEYPRESS_STARTED:
3257 conn->passkey_entered = 0;
3258 return;
3259
3260 case HCI_KEYPRESS_ENTERED:
3261 conn->passkey_entered++;
3262 break;
3263
3264 case HCI_KEYPRESS_ERASED:
3265 conn->passkey_entered--;
3266 break;
3267
3268 case HCI_KEYPRESS_CLEARED:
3269 conn->passkey_entered = 0;
3270 break;
3271
3272 case HCI_KEYPRESS_COMPLETED:
3273 return;
3274 }
3275
3276 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3277 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3278 conn->dst_type, conn->passkey_notify,
3279 conn->passkey_entered);
3280}
3281
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003282static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3283 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003284{
3285 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3286 struct hci_conn *conn;
3287
3288 BT_DBG("%s", hdev->name);
3289
3290 hci_dev_lock(hdev);
3291
3292 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003293 if (!conn)
3294 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003295
Johan Hedberg2a611692011-02-19 12:06:00 -03003296 /* To avoid duplicate auth_failed events to user space we check
3297 * the HCI_CONN_AUTH_PEND flag which will be set if we
3298 * initiated the authentication. A traditional auth_complete
3299 * event gets always produced as initiator and is also mapped to
3300 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003301 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003302 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003303 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003304
David Herrmann76a68ba2013-04-06 20:28:37 +02003305 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003306
3307unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003308 hci_dev_unlock(hdev);
3309}
3310
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003311static void hci_remote_host_features_evt(struct hci_dev *hdev,
3312 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003313{
3314 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3315 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003316 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003317
3318 BT_DBG("%s", hdev->name);
3319
3320 hci_dev_lock(hdev);
3321
Johan Hedbergcad718e2013-04-17 15:00:51 +03003322 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3323 if (conn)
3324 memcpy(conn->features[1], ev->features, 8);
3325
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003326 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3327 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003328 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003329
3330 hci_dev_unlock(hdev);
3331}
3332
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003333static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3334 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003335{
3336 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3337 struct oob_data *data;
3338
3339 BT_DBG("%s", hdev->name);
3340
3341 hci_dev_lock(hdev);
3342
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003343 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003344 goto unlock;
3345
Szymon Janc2763eda2011-03-22 13:12:22 +01003346 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3347 if (data) {
3348 struct hci_cp_remote_oob_data_reply cp;
3349
3350 bacpy(&cp.bdaddr, &ev->bdaddr);
3351 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3352 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3353
3354 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003355 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003356 } else {
3357 struct hci_cp_remote_oob_data_neg_reply cp;
3358
3359 bacpy(&cp.bdaddr, &ev->bdaddr);
3360 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003361 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003362 }
3363
Szymon Jance1ba1f12011-04-06 13:01:59 +02003364unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003365 hci_dev_unlock(hdev);
3366}
3367
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003368static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3369 struct sk_buff *skb)
3370{
3371 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3372 struct hci_conn *hcon, *bredr_hcon;
3373
3374 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3375 ev->status);
3376
3377 hci_dev_lock(hdev);
3378
3379 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3380 if (!hcon) {
3381 hci_dev_unlock(hdev);
3382 return;
3383 }
3384
3385 if (ev->status) {
3386 hci_conn_del(hcon);
3387 hci_dev_unlock(hdev);
3388 return;
3389 }
3390
3391 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3392
3393 hcon->state = BT_CONNECTED;
3394 bacpy(&hcon->dst, &bredr_hcon->dst);
3395
3396 hci_conn_hold(hcon);
3397 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003398 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003399
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003400 hci_conn_add_sysfs(hcon);
3401
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003402 amp_physical_cfm(bredr_hcon, hcon);
3403
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003404 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003405}
3406
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003407static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3408{
3409 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3410 struct hci_conn *hcon;
3411 struct hci_chan *hchan;
3412 struct amp_mgr *mgr;
3413
3414 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3415 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3416 ev->status);
3417
3418 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3419 if (!hcon)
3420 return;
3421
3422 /* Create AMP hchan */
3423 hchan = hci_chan_create(hcon);
3424 if (!hchan)
3425 return;
3426
3427 hchan->handle = le16_to_cpu(ev->handle);
3428
3429 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3430
3431 mgr = hcon->amp_mgr;
3432 if (mgr && mgr->bredr_chan) {
3433 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3434
3435 l2cap_chan_lock(bredr_chan);
3436
3437 bredr_chan->conn->mtu = hdev->block_mtu;
3438 l2cap_logical_cfm(bredr_chan, hchan, 0);
3439 hci_conn_hold(hcon);
3440
3441 l2cap_chan_unlock(bredr_chan);
3442 }
3443}
3444
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003445static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3446 struct sk_buff *skb)
3447{
3448 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3449 struct hci_chan *hchan;
3450
3451 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3452 le16_to_cpu(ev->handle), ev->status);
3453
3454 if (ev->status)
3455 return;
3456
3457 hci_dev_lock(hdev);
3458
3459 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3460 if (!hchan)
3461 goto unlock;
3462
3463 amp_destroy_logical_link(hchan, ev->reason);
3464
3465unlock:
3466 hci_dev_unlock(hdev);
3467}
3468
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003469static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3470 struct sk_buff *skb)
3471{
3472 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3473 struct hci_conn *hcon;
3474
3475 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3476
3477 if (ev->status)
3478 return;
3479
3480 hci_dev_lock(hdev);
3481
3482 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3483 if (hcon) {
3484 hcon->state = BT_CLOSED;
3485 hci_conn_del(hcon);
3486 }
3487
3488 hci_dev_unlock(hdev);
3489}
3490
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003491static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003492{
3493 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3494 struct hci_conn *conn;
3495
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003496 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003497
3498 hci_dev_lock(hdev);
3499
Andre Guedesb47a09b2012-07-27 15:10:15 -03003500 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003501 if (!conn) {
3502 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3503 if (!conn) {
3504 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003505 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003506 }
Andre Guedes29b79882011-05-31 14:20:54 -03003507
3508 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003509
3510 if (ev->role == LE_CONN_ROLE_MASTER) {
3511 conn->out = true;
3512 conn->link_mode |= HCI_LM_MASTER;
3513 }
Ville Tervob62f3282011-02-10 22:38:50 -03003514 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003515
Andre Guedescd17dec2012-07-27 15:10:16 -03003516 if (ev->status) {
3517 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3518 conn->dst_type, ev->status);
3519 hci_proto_connect_cfm(conn, ev->status);
3520 conn->state = BT_CLOSED;
3521 hci_conn_del(conn);
3522 goto unlock;
3523 }
3524
Johan Hedbergb644ba32012-01-17 21:48:47 +02003525 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3526 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003527 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003528
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003529 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003530 conn->handle = __le16_to_cpu(ev->handle);
3531 conn->state = BT_CONNECTED;
3532
Ville Tervofcd89c02011-02-10 22:38:47 -03003533 hci_conn_add_sysfs(conn);
3534
3535 hci_proto_connect_cfm(conn, ev->status);
3536
3537unlock:
3538 hci_dev_unlock(hdev);
3539}
3540
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003541static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003542{
Andre Guedese95beb42011-09-26 20:48:35 -03003543 u8 num_reports = skb->data[0];
3544 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003545 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003546
Andre Guedese95beb42011-09-26 20:48:35 -03003547 while (num_reports--) {
3548 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003549
Andre Guedes3c9e9192012-01-10 18:20:50 -03003550 rssi = ev->data[ev->length];
3551 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003552 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003553
Andre Guedese95beb42011-09-26 20:48:35 -03003554 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003555 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003556}
3557
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003558static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003559{
3560 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3561 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003562 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003563 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003564 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003565
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003566 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003567
3568 hci_dev_lock(hdev);
3569
3570 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003571 if (conn == NULL)
3572 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003573
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003574 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3575 if (ltk == NULL)
3576 goto not_found;
3577
3578 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003579 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003580
3581 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003582 conn->pending_sec_level = BT_SECURITY_HIGH;
3583 else
3584 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003585
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003586 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003587
3588 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3589
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003590 if (ltk->type & HCI_SMP_STK) {
3591 list_del(&ltk->list);
3592 kfree(ltk);
3593 }
3594
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003595 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003596
3597 return;
3598
3599not_found:
3600 neg.handle = ev->handle;
3601 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3602 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003603}
3604
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003605static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003606{
3607 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3608
3609 skb_pull(skb, sizeof(*le_ev));
3610
3611 switch (le_ev->subevent) {
3612 case HCI_EV_LE_CONN_COMPLETE:
3613 hci_le_conn_complete_evt(hdev, skb);
3614 break;
3615
Andre Guedes9aa04c92011-05-26 16:23:51 -03003616 case HCI_EV_LE_ADVERTISING_REPORT:
3617 hci_le_adv_report_evt(hdev, skb);
3618 break;
3619
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003620 case HCI_EV_LE_LTK_REQ:
3621 hci_le_ltk_request_evt(hdev, skb);
3622 break;
3623
Ville Tervofcd89c02011-02-10 22:38:47 -03003624 default:
3625 break;
3626 }
3627}
3628
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003629static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3630{
3631 struct hci_ev_channel_selected *ev = (void *) skb->data;
3632 struct hci_conn *hcon;
3633
3634 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3635
3636 skb_pull(skb, sizeof(*ev));
3637
3638 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3639 if (!hcon)
3640 return;
3641
3642 amp_read_loc_assoc_final_data(hdev, hcon);
3643}
3644
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3646{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003647 struct hci_event_hdr *hdr = (void *) skb->data;
3648 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003649
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003650 hci_dev_lock(hdev);
3651
3652 /* Received events are (currently) only needed when a request is
3653 * ongoing so avoid unnecessary memory allocation.
3654 */
3655 if (hdev->req_status == HCI_REQ_PEND) {
3656 kfree_skb(hdev->recv_evt);
3657 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3658 }
3659
3660 hci_dev_unlock(hdev);
3661
Linus Torvalds1da177e2005-04-16 15:20:36 -07003662 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3663
Johan Hedberg02350a72013-04-03 21:50:29 +03003664 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02003665 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
3666 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03003667
3668 hci_req_cmd_complete(hdev, opcode, 0);
3669 }
3670
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003671 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672 case HCI_EV_INQUIRY_COMPLETE:
3673 hci_inquiry_complete_evt(hdev, skb);
3674 break;
3675
3676 case HCI_EV_INQUIRY_RESULT:
3677 hci_inquiry_result_evt(hdev, skb);
3678 break;
3679
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003680 case HCI_EV_CONN_COMPLETE:
3681 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003682 break;
3683
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684 case HCI_EV_CONN_REQUEST:
3685 hci_conn_request_evt(hdev, skb);
3686 break;
3687
Linus Torvalds1da177e2005-04-16 15:20:36 -07003688 case HCI_EV_DISCONN_COMPLETE:
3689 hci_disconn_complete_evt(hdev, skb);
3690 break;
3691
Linus Torvalds1da177e2005-04-16 15:20:36 -07003692 case HCI_EV_AUTH_COMPLETE:
3693 hci_auth_complete_evt(hdev, skb);
3694 break;
3695
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003696 case HCI_EV_REMOTE_NAME:
3697 hci_remote_name_evt(hdev, skb);
3698 break;
3699
Linus Torvalds1da177e2005-04-16 15:20:36 -07003700 case HCI_EV_ENCRYPT_CHANGE:
3701 hci_encrypt_change_evt(hdev, skb);
3702 break;
3703
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003704 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3705 hci_change_link_key_complete_evt(hdev, skb);
3706 break;
3707
3708 case HCI_EV_REMOTE_FEATURES:
3709 hci_remote_features_evt(hdev, skb);
3710 break;
3711
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003712 case HCI_EV_CMD_COMPLETE:
3713 hci_cmd_complete_evt(hdev, skb);
3714 break;
3715
3716 case HCI_EV_CMD_STATUS:
3717 hci_cmd_status_evt(hdev, skb);
3718 break;
3719
3720 case HCI_EV_ROLE_CHANGE:
3721 hci_role_change_evt(hdev, skb);
3722 break;
3723
3724 case HCI_EV_NUM_COMP_PKTS:
3725 hci_num_comp_pkts_evt(hdev, skb);
3726 break;
3727
3728 case HCI_EV_MODE_CHANGE:
3729 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003730 break;
3731
3732 case HCI_EV_PIN_CODE_REQ:
3733 hci_pin_code_request_evt(hdev, skb);
3734 break;
3735
3736 case HCI_EV_LINK_KEY_REQ:
3737 hci_link_key_request_evt(hdev, skb);
3738 break;
3739
3740 case HCI_EV_LINK_KEY_NOTIFY:
3741 hci_link_key_notify_evt(hdev, skb);
3742 break;
3743
3744 case HCI_EV_CLOCK_OFFSET:
3745 hci_clock_offset_evt(hdev, skb);
3746 break;
3747
Marcel Holtmanna8746412008-07-14 20:13:46 +02003748 case HCI_EV_PKT_TYPE_CHANGE:
3749 hci_pkt_type_change_evt(hdev, skb);
3750 break;
3751
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003752 case HCI_EV_PSCAN_REP_MODE:
3753 hci_pscan_rep_mode_evt(hdev, skb);
3754 break;
3755
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003756 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3757 hci_inquiry_result_with_rssi_evt(hdev, skb);
3758 break;
3759
3760 case HCI_EV_REMOTE_EXT_FEATURES:
3761 hci_remote_ext_features_evt(hdev, skb);
3762 break;
3763
3764 case HCI_EV_SYNC_CONN_COMPLETE:
3765 hci_sync_conn_complete_evt(hdev, skb);
3766 break;
3767
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003768 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3769 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003770 break;
3771
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003772 case HCI_EV_KEY_REFRESH_COMPLETE:
3773 hci_key_refresh_complete_evt(hdev, skb);
3774 break;
3775
Marcel Holtmann04936842008-07-14 20:13:48 +02003776 case HCI_EV_IO_CAPA_REQUEST:
3777 hci_io_capa_request_evt(hdev, skb);
3778 break;
3779
Johan Hedberg03b555e2011-01-04 15:40:05 +02003780 case HCI_EV_IO_CAPA_REPLY:
3781 hci_io_capa_reply_evt(hdev, skb);
3782 break;
3783
Johan Hedberga5c29682011-02-19 12:05:57 -03003784 case HCI_EV_USER_CONFIRM_REQUEST:
3785 hci_user_confirm_request_evt(hdev, skb);
3786 break;
3787
Brian Gix1143d452011-11-23 08:28:34 -08003788 case HCI_EV_USER_PASSKEY_REQUEST:
3789 hci_user_passkey_request_evt(hdev, skb);
3790 break;
3791
Johan Hedberg92a25252012-09-06 18:39:26 +03003792 case HCI_EV_USER_PASSKEY_NOTIFY:
3793 hci_user_passkey_notify_evt(hdev, skb);
3794 break;
3795
3796 case HCI_EV_KEYPRESS_NOTIFY:
3797 hci_keypress_notify_evt(hdev, skb);
3798 break;
3799
Marcel Holtmann04936842008-07-14 20:13:48 +02003800 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3801 hci_simple_pair_complete_evt(hdev, skb);
3802 break;
3803
Marcel Holtmann41a96212008-07-14 20:13:48 +02003804 case HCI_EV_REMOTE_HOST_FEATURES:
3805 hci_remote_host_features_evt(hdev, skb);
3806 break;
3807
Ville Tervofcd89c02011-02-10 22:38:47 -03003808 case HCI_EV_LE_META:
3809 hci_le_meta_evt(hdev, skb);
3810 break;
3811
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003812 case HCI_EV_CHANNEL_SELECTED:
3813 hci_chan_selected_evt(hdev, skb);
3814 break;
3815
Szymon Janc2763eda2011-03-22 13:12:22 +01003816 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3817 hci_remote_oob_data_request_evt(hdev, skb);
3818 break;
3819
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003820 case HCI_EV_PHY_LINK_COMPLETE:
3821 hci_phy_link_complete_evt(hdev, skb);
3822 break;
3823
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003824 case HCI_EV_LOGICAL_LINK_COMPLETE:
3825 hci_loglink_complete_evt(hdev, skb);
3826 break;
3827
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003828 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3829 hci_disconn_loglink_complete_evt(hdev, skb);
3830 break;
3831
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003832 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3833 hci_disconn_phylink_complete_evt(hdev, skb);
3834 break;
3835
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003836 case HCI_EV_NUM_COMP_BLOCKS:
3837 hci_num_comp_blocks_evt(hdev, skb);
3838 break;
3839
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003840 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003841 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003842 break;
3843 }
3844
3845 kfree_skb(skb);
3846 hdev->stat.evt_rx++;
3847}