blob: 0dd85a0c05f4ddfa502eda0f78ae07116b27a123 [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 Guedese6d465c2011-11-09 17:14:26 -030043 if (status) {
44 hci_dev_lock(hdev);
45 mgmt_stop_discovery_failed(hdev, status);
46 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020047 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030048 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Andre Guedes89352e72011-11-04 14:16:53 -030050 clear_bit(HCI_INQUIRY, &hdev->flags);
51
Johan Hedberg56e5cb82011-11-08 20:40:16 +020052 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020053 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020054 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010055
Johan Hedberg9238f362013-03-05 20:37:48 +020056 hci_req_cmd_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010057
Marcel Holtmanna9de9242007-10-20 13:33:56 +020058 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070059}
60
Andre Guedes4d934832012-03-21 00:03:35 -030061static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
62{
63 __u8 status = *((__u8 *) skb->data);
64
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030065 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030066
67 if (status)
68 return;
69
70 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030071}
72
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020075 __u8 status = *((__u8 *) skb->data);
76
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030077 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020078
79 if (status)
80 return;
81
Andre Guedesae854a72012-03-21 00:03:36 -030082 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
83
Marcel Holtmanna9de9242007-10-20 13:33:56 +020084 hci_conn_check_pending(hdev);
85}
86
Gustavo Padovan807deac2012-05-17 00:36:24 -030087static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
88 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020089{
90 BT_DBG("%s", hdev->name);
91}
92
93static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
94{
95 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030098 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 if (rp->status)
101 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200103 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
106 if (conn) {
107 if (rp->role)
108 conn->link_mode &= ~HCI_LM_MASTER;
109 else
110 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200112
113 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114}
115
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200116static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
117{
118 struct hci_rp_read_link_policy *rp = (void *) skb->data;
119 struct hci_conn *conn;
120
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300121 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200122
123 if (rp->status)
124 return;
125
126 hci_dev_lock(hdev);
127
128 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
129 if (conn)
130 conn->link_policy = __le16_to_cpu(rp->policy);
131
132 hci_dev_unlock(hdev);
133}
134
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200137 struct hci_rp_write_link_policy *rp = (void *) skb->data;
138 struct hci_conn *conn;
139 void *sent;
140
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300141 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200142
143 if (rp->status)
144 return;
145
146 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
147 if (!sent)
148 return;
149
150 hci_dev_lock(hdev);
151
152 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200153 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700154 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200155
156 hci_dev_unlock(hdev);
157}
158
Gustavo Padovan807deac2012-05-17 00:36:24 -0300159static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
160 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200161{
162 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
163
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300164 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200165
166 if (rp->status)
167 return;
168
169 hdev->link_policy = __le16_to_cpu(rp->policy);
170}
171
Gustavo Padovan807deac2012-05-17 00:36:24 -0300172static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
173 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200174{
175 __u8 status = *((__u8 *) skb->data);
176 void *sent;
177
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300178 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200179
180 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
181 if (!sent)
182 return;
183
184 if (!status)
185 hdev->link_policy = get_unaligned_le16(sent);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200186}
187
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200188static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
189{
190 __u8 status = *((__u8 *) skb->data);
191
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300192 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200193
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300194 clear_bit(HCI_RESET, &hdev->flags);
195
Johan Hedberga297e972012-02-21 17:55:47 +0200196 /* Reset all non-persistent flags */
Andre Guedesae854a72012-03-21 00:03:36 -0300197 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN) | BIT(HCI_PENDING_CLASS) |
198 BIT(HCI_PERIODIC_INQ));
Andre Guedes69775ff2012-02-23 16:50:05 +0200199
200 hdev->discovery.state = DISCOVERY_STOPPED;
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100201 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
202 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100203
204 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
205 hdev->adv_data_len = 0;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200206}
207
208static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
209{
210 __u8 status = *((__u8 *) skb->data);
211 void *sent;
212
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300213 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200214
215 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
216 if (!sent)
217 return;
218
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200219 hci_dev_lock(hdev);
220
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200221 if (test_bit(HCI_MGMT, &hdev->dev_flags))
222 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200223 else if (!status)
224 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200225
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200226 hci_dev_unlock(hdev);
Johan Hedberg3159d382012-02-24 13:47:56 +0200227
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100228 if (!status && !test_bit(HCI_INIT, &hdev->flags))
229 hci_update_ad(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200230}
231
232static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
233{
234 struct hci_rp_read_local_name *rp = (void *) skb->data;
235
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300236 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200237
238 if (rp->status)
239 return;
240
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200241 if (test_bit(HCI_SETUP, &hdev->dev_flags))
242 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200243}
244
245static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
246{
247 __u8 status = *((__u8 *) skb->data);
248 void *sent;
249
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300250 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200251
252 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
253 if (!sent)
254 return;
255
256 if (!status) {
257 __u8 param = *((__u8 *) sent);
258
259 if (param == AUTH_ENABLED)
260 set_bit(HCI_AUTH, &hdev->flags);
261 else
262 clear_bit(HCI_AUTH, &hdev->flags);
263 }
264
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200265 if (test_bit(HCI_MGMT, &hdev->dev_flags))
266 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200267}
268
269static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
270{
271 __u8 status = *((__u8 *) skb->data);
272 void *sent;
273
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300274 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200275
276 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
277 if (!sent)
278 return;
279
280 if (!status) {
281 __u8 param = *((__u8 *) sent);
282
283 if (param)
284 set_bit(HCI_ENCRYPT, &hdev->flags);
285 else
286 clear_bit(HCI_ENCRYPT, &hdev->flags);
287 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200288}
289
290static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
291{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200292 __u8 param, status = *((__u8 *) skb->data);
293 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200294 void *sent;
295
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300296 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200297
298 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
299 if (!sent)
300 return;
301
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200302 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200303
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200304 hci_dev_lock(hdev);
305
Mikel Astizfa1bd912012-08-09 09:52:29 +0200306 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200307 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200308 hdev->discov_timeout = 0;
309 goto done;
310 }
311
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200312 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
313 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200314
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200315 if (param & SCAN_INQUIRY) {
316 set_bit(HCI_ISCAN, &hdev->flags);
317 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200318 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200319 if (hdev->discov_timeout > 0) {
320 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
321 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300322 to);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200323 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200324 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200325 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200326
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327 if (param & SCAN_PAGE) {
328 set_bit(HCI_PSCAN, &hdev->flags);
329 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200330 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200331 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200332 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200333
334done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200335 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200336}
337
338static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
339{
340 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
341
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300342 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200343
344 if (rp->status)
345 return;
346
347 memcpy(hdev->dev_class, rp->dev_class, 3);
348
349 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300350 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200351}
352
353static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
354{
355 __u8 status = *((__u8 *) skb->data);
356 void *sent;
357
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300358 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200359
360 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
361 if (!sent)
362 return;
363
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100364 hci_dev_lock(hdev);
365
366 if (status == 0)
367 memcpy(hdev->dev_class, sent, 3);
368
369 if (test_bit(HCI_MGMT, &hdev->dev_flags))
370 mgmt_set_class_of_dev_complete(hdev, sent, status);
371
372 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200373}
374
375static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
376{
377 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200379
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300380 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200381
382 if (rp->status)
383 return;
384
385 setting = __le16_to_cpu(rp->voice_setting);
386
Marcel Holtmannf383f272008-07-14 20:13:47 +0200387 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200388 return;
389
390 hdev->voice_setting = setting;
391
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300392 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200393
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200394 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200395 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200396}
397
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300398static void hci_cc_write_voice_setting(struct hci_dev *hdev,
399 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200400{
401 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200402 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 void *sent;
404
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300405 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
Marcel Holtmannf383f272008-07-14 20:13:47 +0200407 if (status)
408 return;
409
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200410 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
411 if (!sent)
412 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413
Marcel Holtmannf383f272008-07-14 20:13:47 +0200414 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415
Marcel Holtmannf383f272008-07-14 20:13:47 +0200416 if (hdev->voice_setting == setting)
417 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
Marcel Holtmannf383f272008-07-14 20:13:47 +0200419 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300421 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200422
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200423 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200424 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425}
426
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200427static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200429 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300431 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432}
433
Marcel Holtmann333140b2008-07-14 20:13:48 +0200434static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
435{
436 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300437 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200438
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300439 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200440
Marcel Holtmann333140b2008-07-14 20:13:48 +0200441 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
442 if (!sent)
443 return;
444
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300445 if (!status) {
446 if (sent->mode)
447 hdev->host_features[0] |= LMP_HOST_SSP;
448 else
449 hdev->host_features[0] &= ~LMP_HOST_SSP;
450 }
451
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200452 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300453 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200454 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300455 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200456 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
457 else
458 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
459 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200460}
461
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200462static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
463{
464 struct hci_rp_read_local_version *rp = (void *) skb->data;
465
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300466 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200467
468 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200469 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200470
471 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200472 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200473 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200474 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200475 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200476
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300477 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300478 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200479}
480
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300481static void hci_cc_read_local_commands(struct hci_dev *hdev,
482 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200483{
484 struct hci_rp_read_local_commands *rp = (void *) skb->data;
485
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300486 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200487
Johan Hedberg2177bab2013-03-05 20:37:43 +0200488 if (!rp->status)
489 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200490}
491
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300492static void hci_cc_read_local_features(struct hci_dev *hdev,
493 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200494{
495 struct hci_rp_read_local_features *rp = (void *) skb->data;
496
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300497 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200498
499 if (rp->status)
500 return;
501
502 memcpy(hdev->features, rp->features, 8);
503
504 /* Adjust default settings according to features
505 * supported by device. */
506
507 if (hdev->features[0] & LMP_3SLOT)
508 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
509
510 if (hdev->features[0] & LMP_5SLOT)
511 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
512
513 if (hdev->features[1] & LMP_HV2) {
514 hdev->pkt_type |= (HCI_HV2);
515 hdev->esco_type |= (ESCO_HV2);
516 }
517
518 if (hdev->features[1] & LMP_HV3) {
519 hdev->pkt_type |= (HCI_HV3);
520 hdev->esco_type |= (ESCO_HV3);
521 }
522
Andre Guedes45db810f2012-07-24 15:03:49 -0300523 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200524 hdev->esco_type |= (ESCO_EV3);
525
526 if (hdev->features[4] & LMP_EV4)
527 hdev->esco_type |= (ESCO_EV4);
528
529 if (hdev->features[4] & LMP_EV5)
530 hdev->esco_type |= (ESCO_EV5);
531
Marcel Holtmannefc76882009-02-06 09:13:37 +0100532 if (hdev->features[5] & LMP_EDR_ESCO_2M)
533 hdev->esco_type |= (ESCO_2EV3);
534
535 if (hdev->features[5] & LMP_EDR_ESCO_3M)
536 hdev->esco_type |= (ESCO_3EV3);
537
538 if (hdev->features[5] & LMP_EDR_3S_ESCO)
539 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
540
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200541 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300542 hdev->features[0], hdev->features[1],
543 hdev->features[2], hdev->features[3],
544 hdev->features[4], hdev->features[5],
545 hdev->features[6], hdev->features[7]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200546}
547
Andre Guedes971e3a42011-06-30 19:20:52 -0300548static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300549 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300550{
551 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
552
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300553 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300554
555 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200556 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300557
Andre Guedesb5b32b62011-12-30 10:34:04 -0300558 switch (rp->page) {
559 case 0:
560 memcpy(hdev->features, rp->features, 8);
561 break;
562 case 1:
563 memcpy(hdev->host_features, rp->features, 8);
564 break;
565 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300566}
567
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200568static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300569 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200570{
571 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
572
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300573 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200574
Johan Hedberg42c6b122013-03-05 20:37:49 +0200575 if (!rp->status)
576 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200577}
578
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200579static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
580{
581 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
582
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300583 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200584
585 if (rp->status)
586 return;
587
588 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
589 hdev->sco_mtu = rp->sco_mtu;
590 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
591 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
592
593 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
594 hdev->sco_mtu = 64;
595 hdev->sco_pkts = 8;
596 }
597
598 hdev->acl_cnt = hdev->acl_pkts;
599 hdev->sco_cnt = hdev->sco_pkts;
600
Gustavo Padovan807deac2012-05-17 00:36:24 -0300601 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
602 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200603}
604
605static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
606{
607 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
608
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300609 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200610
611 if (!rp->status)
612 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200613}
614
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200615static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300616 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200617{
618 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
619
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300620 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200621
622 if (rp->status)
623 return;
624
625 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
626 hdev->block_len = __le16_to_cpu(rp->block_len);
627 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
628
629 hdev->block_cnt = hdev->num_blocks;
630
631 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300632 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200633}
634
Johan Hedberg23bb5762010-12-21 23:01:27 +0200635static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
636{
637 __u8 status = *((__u8 *) skb->data);
638
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300639 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200640}
641
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300642static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300643 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300644{
645 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
646
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300647 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300648
649 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300650 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300651
652 hdev->amp_status = rp->amp_status;
653 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
654 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
655 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
656 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
657 hdev->amp_type = rp->amp_type;
658 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
659 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
660 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
661 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
662
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300663a2mp_rsp:
664 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300665}
666
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300667static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
668 struct sk_buff *skb)
669{
670 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
671 struct amp_assoc *assoc = &hdev->loc_assoc;
672 size_t rem_len, frag_len;
673
674 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
675
676 if (rp->status)
677 goto a2mp_rsp;
678
679 frag_len = skb->len - sizeof(*rp);
680 rem_len = __le16_to_cpu(rp->rem_len);
681
682 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300683 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300684
685 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
686 assoc->offset += frag_len;
687
688 /* Read other fragments */
689 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
690
691 return;
692 }
693
694 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
695 assoc->len = assoc->offset + rem_len;
696 assoc->offset = 0;
697
698a2mp_rsp:
699 /* Send A2MP Rsp when all fragments are received */
700 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300701 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300702}
703
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200704static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300705 struct sk_buff *skb)
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200706{
707 __u8 status = *((__u8 *) skb->data);
708
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300709 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200710}
711
Johan Hedbergd5859e22011-01-25 01:19:58 +0200712static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
713{
714 __u8 status = *((__u8 *) skb->data);
715
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300716 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200717}
718
719static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300720 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200721{
722 __u8 status = *((__u8 *) skb->data);
723
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300724 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200725}
726
727static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300728 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200729{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700730 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200731
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300732 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200733
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700734 if (!rp->status)
735 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200736}
737
738static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
739{
740 __u8 status = *((__u8 *) skb->data);
741
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300742 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200743}
744
Johan Hedberg980e1a52011-01-22 06:10:07 +0200745static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
746{
747 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
748 struct hci_cp_pin_code_reply *cp;
749 struct hci_conn *conn;
750
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300751 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200752
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200753 hci_dev_lock(hdev);
754
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200755 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200756 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200757
Mikel Astizfa1bd912012-08-09 09:52:29 +0200758 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200759 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200760
761 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
762 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200763 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200764
765 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
766 if (conn)
767 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200768
769unlock:
770 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200771}
772
773static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
774{
775 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
776
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300777 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200778
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200779 hci_dev_lock(hdev);
780
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200781 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200782 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300783 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200784
785 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200786}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200787
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300788static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
789 struct sk_buff *skb)
790{
791 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
792
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300793 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300794
795 if (rp->status)
796 return;
797
798 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
799 hdev->le_pkts = rp->le_max_pkt;
800
801 hdev->le_cnt = hdev->le_pkts;
802
803 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300804}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200805
Johan Hedberg60e77322013-01-22 14:01:59 +0200806static void hci_cc_le_read_local_features(struct hci_dev *hdev,
807 struct sk_buff *skb)
808{
809 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
810
811 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
812
813 if (!rp->status)
814 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200815}
816
Johan Hedberg8fa19092012-10-19 20:57:49 +0300817static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
818 struct sk_buff *skb)
819{
820 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
821
822 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
823
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100824 if (!rp->status) {
Johan Hedberg8fa19092012-10-19 20:57:49 +0300825 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100826 if (!test_bit(HCI_INIT, &hdev->flags))
827 hci_update_ad(hdev);
828 }
Johan Hedberg8fa19092012-10-19 20:57:49 +0300829}
830
Johan Hedberge36b04c2012-10-19 20:57:47 +0300831static void hci_cc_le_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
832{
833 __u8 status = *((__u8 *) skb->data);
834
835 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberge36b04c2012-10-19 20:57:47 +0300836}
837
Johan Hedberga5c29682011-02-19 12:05:57 -0300838static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
839{
840 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
841
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300842 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300843
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200844 hci_dev_lock(hdev);
845
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200846 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300847 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
848 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200849
850 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300851}
852
853static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300854 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300855{
856 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
857
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300858 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300859
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200860 hci_dev_lock(hdev);
861
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200862 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200863 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300864 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200865
866 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300867}
868
Brian Gix1143d452011-11-23 08:28:34 -0800869static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
870{
871 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
872
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300873 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800874
875 hci_dev_lock(hdev);
876
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200877 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200878 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300879 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800880
881 hci_dev_unlock(hdev);
882}
883
884static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300885 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800886{
887 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
888
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300889 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800890
891 hci_dev_lock(hdev);
892
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200893 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800894 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300895 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800896
897 hci_dev_unlock(hdev);
898}
899
Szymon Jancc35938b2011-03-22 13:12:21 +0100900static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300901 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100902{
903 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
904
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300905 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100906
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200907 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200908 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100909 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200910 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100911}
912
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100913static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
914{
915 __u8 *sent, status = *((__u8 *) skb->data);
916
917 BT_DBG("%s status 0x%2.2x", hdev->name, status);
918
919 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
920 if (!sent)
921 return;
922
923 hci_dev_lock(hdev);
924
925 if (!status) {
926 if (*sent)
927 set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
928 else
929 clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
930 }
931
932 hci_dev_unlock(hdev);
933
934 if (!test_bit(HCI_INIT, &hdev->flags))
935 hci_update_ad(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100936}
937
Andre Guedes07f7fa52011-12-02 21:13:31 +0900938static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
939{
940 __u8 status = *((__u8 *) skb->data);
941
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300942 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300943
Andre Guedes3fd24152012-02-03 17:48:01 -0300944 if (status) {
945 hci_dev_lock(hdev);
946 mgmt_start_discovery_failed(hdev, status);
947 hci_dev_unlock(hdev);
948 return;
949 }
Andre Guedes07f7fa52011-12-02 21:13:31 +0900950}
951
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300952static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300953 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300954{
955 struct hci_cp_le_set_scan_enable *cp;
956 __u8 status = *((__u8 *) skb->data);
957
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300958 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300959
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300960 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
961 if (!cp)
962 return;
963
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200964 switch (cp->enable) {
965 case LE_SCANNING_ENABLED:
Andre Guedes3fd24152012-02-03 17:48:01 -0300966 if (status) {
967 hci_dev_lock(hdev);
968 mgmt_start_discovery_failed(hdev, status);
969 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300970 return;
Andre Guedes3fd24152012-02-03 17:48:01 -0300971 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300972
Andre Guedesd23264a2011-11-25 20:53:38 -0300973 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
974
Andre Guedesa8f13c82011-09-09 18:56:24 -0300975 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -0300976 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -0300977 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200978 break;
979
980 case LE_SCANNING_DISABLED:
Andre Guedesc9ecc482012-03-15 16:52:08 -0300981 if (status) {
982 hci_dev_lock(hdev);
983 mgmt_stop_discovery_failed(hdev, status);
984 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300985 return;
Andre Guedesc9ecc482012-03-15 16:52:08 -0300986 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300987
Andre Guedesd23264a2011-11-25 20:53:38 -0300988 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
989
Andre Guedesbc3dd332012-03-06 19:37:06 -0300990 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
991 hdev->discovery.state == DISCOVERY_FINDING) {
Andre Guedes5e0452c2012-02-17 20:39:38 -0300992 mgmt_interleaved_discovery(hdev);
993 } else {
994 hci_dev_lock(hdev);
995 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
996 hci_dev_unlock(hdev);
997 }
998
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200999 break;
1000
1001 default:
1002 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1003 break;
Andre Guedes35815082011-05-26 16:23:53 -03001004 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001005}
1006
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001007static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1008 struct sk_buff *skb)
1009{
1010 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1011
1012 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1013
1014 if (!rp->status)
1015 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001016}
1017
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001018static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1019{
1020 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1021
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001022 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001023
1024 if (rp->status)
1025 return;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001026}
1027
1028static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1029{
1030 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1031
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001032 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001033
1034 if (rp->status)
1035 return;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001036}
1037
Johan Hedberg9b008c02013-01-22 14:02:01 +02001038static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1039 struct sk_buff *skb)
1040{
1041 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1042
1043 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1044
1045 if (!rp->status)
1046 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001047}
1048
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001049static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1050 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001051{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001052 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001053 __u8 status = *((__u8 *) skb->data);
1054
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001055 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001056
Johan Hedberg06199cf2012-02-22 16:37:11 +02001057 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001058 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001059 return;
1060
Johan Hedberg8f984df2012-02-28 01:07:22 +02001061 if (!status) {
1062 if (sent->le)
1063 hdev->host_features[0] |= LMP_HOST_LE;
1064 else
1065 hdev->host_features[0] &= ~LMP_HOST_LE;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001066
1067 if (sent->simul)
1068 hdev->host_features[0] |= LMP_HOST_LE_BREDR;
1069 else
1070 hdev->host_features[0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001071 }
1072
1073 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001074 !test_bit(HCI_INIT, &hdev->flags))
Johan Hedberg8f984df2012-02-28 01:07:22 +02001075 mgmt_le_enable_complete(hdev, sent->le, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001076}
1077
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001078static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1079 struct sk_buff *skb)
1080{
1081 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1082
1083 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1084 hdev->name, rp->status, rp->phy_handle);
1085
1086 if (rp->status)
1087 return;
1088
1089 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1090}
1091
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001092static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001093{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001094 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001095
1096 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001097 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001098 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001099 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001100 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001101 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001102 return;
1103 }
1104
Andre Guedes89352e72011-11-04 14:16:53 -03001105 set_bit(HCI_INQUIRY, &hdev->flags);
1106
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001107 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001108 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001109 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001110}
1111
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001112static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001114 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001117 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001118
1119 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 if (!cp)
1121 return;
1122
1123 hci_dev_lock(hdev);
1124
1125 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1126
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001127 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128
1129 if (status) {
1130 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001131 if (status != 0x0c || conn->attempt > 2) {
1132 conn->state = BT_CLOSED;
1133 hci_proto_connect_cfm(conn, status);
1134 hci_conn_del(conn);
1135 } else
1136 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 }
1138 } else {
1139 if (!conn) {
1140 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1141 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001142 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143 conn->link_mode |= HCI_LM_MASTER;
1144 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001145 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 }
1147 }
1148
1149 hci_dev_unlock(hdev);
1150}
1151
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001152static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001154 struct hci_cp_add_sco *cp;
1155 struct hci_conn *acl, *sco;
1156 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001158 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001159
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001160 if (!status)
1161 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001163 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1164 if (!cp)
1165 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001167 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001169 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001170
1171 hci_dev_lock(hdev);
1172
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001173 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001174 if (acl) {
1175 sco = acl->link;
1176 if (sco) {
1177 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001178
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001179 hci_proto_connect_cfm(sco, status);
1180 hci_conn_del(sco);
1181 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001182 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001183
1184 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185}
1186
Marcel Holtmannf8558552008-07-14 20:13:49 +02001187static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1188{
1189 struct hci_cp_auth_requested *cp;
1190 struct hci_conn *conn;
1191
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001192 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001193
1194 if (!status)
1195 return;
1196
1197 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1198 if (!cp)
1199 return;
1200
1201 hci_dev_lock(hdev);
1202
1203 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1204 if (conn) {
1205 if (conn->state == BT_CONFIG) {
1206 hci_proto_connect_cfm(conn, status);
1207 hci_conn_put(conn);
1208 }
1209 }
1210
1211 hci_dev_unlock(hdev);
1212}
1213
1214static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1215{
1216 struct hci_cp_set_conn_encrypt *cp;
1217 struct hci_conn *conn;
1218
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001219 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001220
1221 if (!status)
1222 return;
1223
1224 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1225 if (!cp)
1226 return;
1227
1228 hci_dev_lock(hdev);
1229
1230 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1231 if (conn) {
1232 if (conn->state == BT_CONFIG) {
1233 hci_proto_connect_cfm(conn, status);
1234 hci_conn_put(conn);
1235 }
1236 }
1237
1238 hci_dev_unlock(hdev);
1239}
1240
Johan Hedberg127178d2010-11-18 22:22:29 +02001241static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001242 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001243{
Johan Hedberg392599b2010-11-18 22:22:28 +02001244 if (conn->state != BT_CONFIG || !conn->out)
1245 return 0;
1246
Johan Hedberg765c2a92011-01-19 12:06:52 +05301247 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001248 return 0;
1249
1250 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001251 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001252 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1253 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001254 return 0;
1255
Johan Hedberg392599b2010-11-18 22:22:28 +02001256 return 1;
1257}
1258
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001259static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001260 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001261{
1262 struct hci_cp_remote_name_req cp;
1263
1264 memset(&cp, 0, sizeof(cp));
1265
1266 bacpy(&cp.bdaddr, &e->data.bdaddr);
1267 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1268 cp.pscan_mode = e->data.pscan_mode;
1269 cp.clock_offset = e->data.clock_offset;
1270
1271 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1272}
1273
Johan Hedbergb644ba32012-01-17 21:48:47 +02001274static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001275{
1276 struct discovery_state *discov = &hdev->discovery;
1277 struct inquiry_entry *e;
1278
Johan Hedbergb644ba32012-01-17 21:48:47 +02001279 if (list_empty(&discov->resolve))
1280 return false;
1281
1282 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001283 if (!e)
1284 return false;
1285
Johan Hedbergb644ba32012-01-17 21:48:47 +02001286 if (hci_resolve_name(hdev, e) == 0) {
1287 e->name_state = NAME_PENDING;
1288 return true;
1289 }
1290
1291 return false;
1292}
1293
1294static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001295 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001296{
1297 struct discovery_state *discov = &hdev->discovery;
1298 struct inquiry_entry *e;
1299
1300 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001301 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1302 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001303
1304 if (discov->state == DISCOVERY_STOPPED)
1305 return;
1306
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001307 if (discov->state == DISCOVERY_STOPPING)
1308 goto discov_complete;
1309
1310 if (discov->state != DISCOVERY_RESOLVING)
1311 return;
1312
1313 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001314 /* If the device was not found in a list of found devices names of which
1315 * are pending. there is no need to continue resolving a next name as it
1316 * will be done upon receiving another Remote Name Request Complete
1317 * Event */
1318 if (!e)
1319 return;
1320
1321 list_del(&e->list);
1322 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001323 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001324 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1325 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001326 } else {
1327 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001328 }
1329
Johan Hedbergb644ba32012-01-17 21:48:47 +02001330 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001331 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001332
1333discov_complete:
1334 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1335}
1336
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001337static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1338{
Johan Hedberg127178d2010-11-18 22:22:29 +02001339 struct hci_cp_remote_name_req *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);
Johan Hedberg127178d2010-11-18 22:22:29 +02001343
1344 /* If successful wait for the name req complete event before
1345 * checking for the need to do authentication */
1346 if (!status)
1347 return;
1348
1349 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1350 if (!cp)
1351 return;
1352
1353 hci_dev_lock(hdev);
1354
1355 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001356
1357 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1358 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1359
Johan Hedberg79c6c702011-04-28 11:28:55 -07001360 if (!conn)
1361 goto unlock;
1362
1363 if (!hci_outgoing_auth_needed(hdev, conn))
1364 goto unlock;
1365
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001366 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001367 struct hci_cp_auth_requested cp;
1368 cp.handle = __cpu_to_le16(conn->handle);
1369 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1370 }
1371
Johan Hedberg79c6c702011-04-28 11:28:55 -07001372unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001373 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001374}
1375
Marcel Holtmann769be972008-07-14 20:13:49 +02001376static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1377{
1378 struct hci_cp_read_remote_features *cp;
1379 struct hci_conn *conn;
1380
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001381 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001382
1383 if (!status)
1384 return;
1385
1386 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1387 if (!cp)
1388 return;
1389
1390 hci_dev_lock(hdev);
1391
1392 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1393 if (conn) {
1394 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001395 hci_proto_connect_cfm(conn, status);
1396 hci_conn_put(conn);
1397 }
1398 }
1399
1400 hci_dev_unlock(hdev);
1401}
1402
1403static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1404{
1405 struct hci_cp_read_remote_ext_features *cp;
1406 struct hci_conn *conn;
1407
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001408 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001409
1410 if (!status)
1411 return;
1412
1413 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1414 if (!cp)
1415 return;
1416
1417 hci_dev_lock(hdev);
1418
1419 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1420 if (conn) {
1421 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001422 hci_proto_connect_cfm(conn, status);
1423 hci_conn_put(conn);
1424 }
1425 }
1426
1427 hci_dev_unlock(hdev);
1428}
1429
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001430static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1431{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001432 struct hci_cp_setup_sync_conn *cp;
1433 struct hci_conn *acl, *sco;
1434 __u16 handle;
1435
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001436 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001437
1438 if (!status)
1439 return;
1440
1441 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1442 if (!cp)
1443 return;
1444
1445 handle = __le16_to_cpu(cp->handle);
1446
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001447 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001448
1449 hci_dev_lock(hdev);
1450
1451 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001452 if (acl) {
1453 sco = acl->link;
1454 if (sco) {
1455 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001456
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001457 hci_proto_connect_cfm(sco, status);
1458 hci_conn_del(sco);
1459 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001460 }
1461
1462 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001463}
1464
1465static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1466{
1467 struct hci_cp_sniff_mode *cp;
1468 struct hci_conn *conn;
1469
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001470 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001471
1472 if (!status)
1473 return;
1474
1475 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1476 if (!cp)
1477 return;
1478
1479 hci_dev_lock(hdev);
1480
1481 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001482 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001483 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001484
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001485 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001486 hci_sco_setup(conn, status);
1487 }
1488
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001489 hci_dev_unlock(hdev);
1490}
1491
1492static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1493{
1494 struct hci_cp_exit_sniff_mode *cp;
1495 struct hci_conn *conn;
1496
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001497 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001498
1499 if (!status)
1500 return;
1501
1502 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1503 if (!cp)
1504 return;
1505
1506 hci_dev_lock(hdev);
1507
1508 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001509 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001510 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001511
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001512 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001513 hci_sco_setup(conn, status);
1514 }
1515
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001516 hci_dev_unlock(hdev);
1517}
1518
Johan Hedberg88c3df12012-02-09 14:27:38 +02001519static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1520{
1521 struct hci_cp_disconnect *cp;
1522 struct hci_conn *conn;
1523
1524 if (!status)
1525 return;
1526
1527 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1528 if (!cp)
1529 return;
1530
1531 hci_dev_lock(hdev);
1532
1533 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1534 if (conn)
1535 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001536 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001537
1538 hci_dev_unlock(hdev);
1539}
1540
Ville Tervofcd89c02011-02-10 22:38:47 -03001541static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1542{
Ville Tervofcd89c02011-02-10 22:38:47 -03001543 struct hci_conn *conn;
1544
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001545 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Ville Tervofcd89c02011-02-10 22:38:47 -03001546
Ville Tervofcd89c02011-02-10 22:38:47 -03001547 if (status) {
Andre Guedesf00a06a2012-07-27 15:10:13 -03001548 hci_dev_lock(hdev);
Ville Tervofcd89c02011-02-10 22:38:47 -03001549
Andre Guedes0c95ab72012-07-27 15:10:14 -03001550 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001551 if (!conn) {
1552 hci_dev_unlock(hdev);
1553 return;
1554 }
1555
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001556 BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001557
1558 conn->state = BT_CLOSED;
Andre Guedes0c95ab72012-07-27 15:10:14 -03001559 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Andre Guedesf00a06a2012-07-27 15:10:13 -03001560 conn->dst_type, status);
1561 hci_proto_connect_cfm(conn, status);
1562 hci_conn_del(conn);
1563
1564 hci_dev_unlock(hdev);
1565 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001566}
1567
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001568static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1569{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001570 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001571}
1572
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001573static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1574{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001575 struct hci_cp_create_phy_link *cp;
1576
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001577 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001578
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001579 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1580 if (!cp)
1581 return;
1582
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001583 hci_dev_lock(hdev);
1584
1585 if (status) {
1586 struct hci_conn *hcon;
1587
1588 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1589 if (hcon)
1590 hci_conn_del(hcon);
1591 } else {
1592 amp_write_remote_assoc(hdev, cp->phy_handle);
1593 }
1594
1595 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001596}
1597
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001598static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1599{
1600 struct hci_cp_accept_phy_link *cp;
1601
1602 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1603
1604 if (status)
1605 return;
1606
1607 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1608 if (!cp)
1609 return;
1610
1611 amp_write_remote_assoc(hdev, cp->phy_handle);
1612}
1613
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001614static void hci_cs_create_logical_link(struct hci_dev *hdev, u8 status)
1615{
1616 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1617}
1618
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001619static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001620{
1621 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001622 struct discovery_state *discov = &hdev->discovery;
1623 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001624
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001625 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001626
Johan Hedberg9238f362013-03-05 20:37:48 +02001627 hci_req_cmd_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001628
1629 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001630
1631 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1632 return;
1633
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001634 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001635 return;
1636
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001637 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001638
Andre Guedes343f9352012-02-17 20:39:37 -03001639 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001640 goto unlock;
1641
1642 if (list_empty(&discov->resolve)) {
1643 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1644 goto unlock;
1645 }
1646
1647 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1648 if (e && hci_resolve_name(hdev, e) == 0) {
1649 e->name_state = NAME_PENDING;
1650 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1651 } else {
1652 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1653 }
1654
1655unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001656 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001657}
1658
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001659static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001661 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001662 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 int num_rsp = *((__u8 *) skb->data);
1664
1665 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1666
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001667 if (!num_rsp)
1668 return;
1669
Andre Guedes1519cc12012-03-21 00:03:38 -03001670 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1671 return;
1672
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001674
Johan Hedberge17acd42011-03-30 23:57:16 +03001675 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001676 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001677
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678 bacpy(&data.bdaddr, &info->bdaddr);
1679 data.pscan_rep_mode = info->pscan_rep_mode;
1680 data.pscan_period_mode = info->pscan_period_mode;
1681 data.pscan_mode = info->pscan_mode;
1682 memcpy(data.dev_class, info->dev_class, 3);
1683 data.clock_offset = info->clock_offset;
1684 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001685 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001686
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001687 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001688 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001689 info->dev_class, 0, !name_known, ssp, NULL,
1690 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001692
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 hci_dev_unlock(hdev);
1694}
1695
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001696static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001698 struct hci_ev_conn_complete *ev = (void *) skb->data;
1699 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001701 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001702
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001704
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001705 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001706 if (!conn) {
1707 if (ev->link_type != SCO_LINK)
1708 goto unlock;
1709
1710 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1711 if (!conn)
1712 goto unlock;
1713
1714 conn->type = SCO_LINK;
1715 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001716
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001717 if (!ev->status) {
1718 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001719
1720 if (conn->type == ACL_LINK) {
1721 conn->state = BT_CONFIG;
1722 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001723
1724 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1725 !hci_find_link_key(hdev, &ev->bdaddr))
1726 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1727 else
1728 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001729 } else
1730 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001731
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001732 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001733 hci_conn_add_sysfs(conn);
1734
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001735 if (test_bit(HCI_AUTH, &hdev->flags))
1736 conn->link_mode |= HCI_LM_AUTH;
1737
1738 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1739 conn->link_mode |= HCI_LM_ENCRYPT;
1740
1741 /* Get remote features */
1742 if (conn->type == ACL_LINK) {
1743 struct hci_cp_read_remote_features cp;
1744 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001745 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001746 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001747 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001748
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001749 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001750 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001751 struct hci_cp_change_conn_ptype cp;
1752 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001753 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001754 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1755 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001756 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001757 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001758 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001759 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001760 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001761 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001762 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001763
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001764 if (conn->type == ACL_LINK)
1765 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001766
Marcel Holtmann769be972008-07-14 20:13:49 +02001767 if (ev->status) {
1768 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001769 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001770 } else if (ev->link_type != ACL_LINK)
1771 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001772
1773unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001775
1776 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777}
1778
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001779void hci_conn_accept(struct hci_conn *conn, int mask)
1780{
1781 struct hci_dev *hdev = conn->hdev;
1782
1783 BT_DBG("conn %p", conn);
1784
1785 conn->state = BT_CONFIG;
1786
1787 if (!lmp_esco_capable(hdev)) {
1788 struct hci_cp_accept_conn_req cp;
1789
1790 bacpy(&cp.bdaddr, &conn->dst);
1791
1792 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1793 cp.role = 0x00; /* Become master */
1794 else
1795 cp.role = 0x01; /* Remain slave */
1796
1797 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
1798 } else /* lmp_esco_capable(hdev)) */ {
1799 struct hci_cp_accept_sync_conn_req cp;
1800
1801 bacpy(&cp.bdaddr, &conn->dst);
1802 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1803
1804 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1805 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1806 cp.max_latency = __constant_cpu_to_le16(0xffff);
1807 cp.content_format = cpu_to_le16(hdev->voice_setting);
1808 cp.retrans_effort = 0xff;
1809
1810 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1811 sizeof(cp), &cp);
1812 }
1813}
1814
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001815static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001817 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001819 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001821 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001822 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001824 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1825 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
Szymon Janc138d22e2011-02-17 16:44:23 +01001827 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001828 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001830 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832
1833 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001834
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001835 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1836 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001837 memcpy(ie->data.dev_class, ev->dev_class, 3);
1838
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001839 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1840 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001842 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1843 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001844 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 hci_dev_unlock(hdev);
1846 return;
1847 }
1848 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001849
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001851
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 hci_dev_unlock(hdev);
1853
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001854 if (ev->link_type == ACL_LINK ||
1855 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001856 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001857 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001859 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001861 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1862 cp.role = 0x00; /* Become master */
1863 else
1864 cp.role = 0x01; /* Remain slave */
1865
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001866 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1867 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001868 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001869 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001870 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001871
1872 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001873 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001874
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001875 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1876 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1877 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001878 cp.content_format = cpu_to_le16(hdev->voice_setting);
1879 cp.retrans_effort = 0xff;
1880
1881 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001882 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001883 } else {
1884 conn->state = BT_CONNECT2;
1885 hci_proto_connect_cfm(conn, 0);
1886 hci_conn_put(conn);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001887 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 } else {
1889 /* Connection rejected */
1890 struct hci_cp_reject_conn_req cp;
1891
1892 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001893 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001894 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 }
1896}
1897
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001898static u8 hci_to_mgmt_reason(u8 err)
1899{
1900 switch (err) {
1901 case HCI_ERROR_CONNECTION_TIMEOUT:
1902 return MGMT_DEV_DISCONN_TIMEOUT;
1903 case HCI_ERROR_REMOTE_USER_TERM:
1904 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1905 case HCI_ERROR_REMOTE_POWER_OFF:
1906 return MGMT_DEV_DISCONN_REMOTE;
1907 case HCI_ERROR_LOCAL_HOST_TERM:
1908 return MGMT_DEV_DISCONN_LOCAL_HOST;
1909 default:
1910 return MGMT_DEV_DISCONN_UNKNOWN;
1911 }
1912}
1913
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001914static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001916 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001917 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001919 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 hci_dev_lock(hdev);
1922
Marcel Holtmann04837f62006-07-03 10:02:33 +02001923 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001924 if (!conn)
1925 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001926
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001927 if (ev->status == 0)
1928 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929
Johan Hedbergb644ba32012-01-17 21:48:47 +02001930 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001931 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001932 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001933 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001934 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001935 } else {
1936 u8 reason = hci_to_mgmt_reason(ev->reason);
1937
Johan Hedbergafc747a2012-01-15 18:11:07 +02001938 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001939 conn->dst_type, reason);
1940 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001941 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001942
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001943 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301944 if (conn->type == ACL_LINK && conn->flush_key)
1945 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001946 hci_proto_disconn_cfm(conn, ev->reason);
1947 hci_conn_del(conn);
1948 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001949
1950unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951 hci_dev_unlock(hdev);
1952}
1953
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001954static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001955{
1956 struct hci_ev_auth_complete *ev = (void *) skb->data;
1957 struct hci_conn *conn;
1958
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001959 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001960
1961 hci_dev_lock(hdev);
1962
1963 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001964 if (!conn)
1965 goto unlock;
1966
1967 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001968 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001969 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001970 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001971 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001972 conn->link_mode |= HCI_LM_AUTH;
1973 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001974 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001975 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001976 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001977 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001978 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001979
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001980 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1981 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001982
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001983 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001984 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001985 struct hci_cp_set_conn_encrypt cp;
1986 cp.handle = ev->handle;
1987 cp.encrypt = 0x01;
1988 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001989 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001990 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001991 conn->state = BT_CONNECTED;
1992 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001993 hci_conn_put(conn);
1994 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001995 } else {
1996 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001997
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001998 hci_conn_hold(conn);
1999 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
2000 hci_conn_put(conn);
2001 }
2002
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002003 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002004 if (!ev->status) {
2005 struct hci_cp_set_conn_encrypt cp;
2006 cp.handle = ev->handle;
2007 cp.encrypt = 0x01;
2008 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002009 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002010 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002011 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002012 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002013 }
2014 }
2015
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002016unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002017 hci_dev_unlock(hdev);
2018}
2019
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002020static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002021{
Johan Hedberg127178d2010-11-18 22:22:29 +02002022 struct hci_ev_remote_name *ev = (void *) skb->data;
2023 struct hci_conn *conn;
2024
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002025 BT_DBG("%s", hdev->name);
2026
2027 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002028
2029 hci_dev_lock(hdev);
2030
2031 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002032
2033 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2034 goto check_auth;
2035
2036 if (ev->status == 0)
2037 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002038 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002039 else
2040 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2041
2042check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002043 if (!conn)
2044 goto unlock;
2045
2046 if (!hci_outgoing_auth_needed(hdev, conn))
2047 goto unlock;
2048
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002049 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002050 struct hci_cp_auth_requested cp;
2051 cp.handle = __cpu_to_le16(conn->handle);
2052 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2053 }
2054
Johan Hedberg79c6c702011-04-28 11:28:55 -07002055unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002056 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002057}
2058
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002059static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002060{
2061 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2062 struct hci_conn *conn;
2063
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002064 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002065
2066 hci_dev_lock(hdev);
2067
2068 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2069 if (conn) {
2070 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002071 if (ev->encrypt) {
2072 /* Encryption implies authentication */
2073 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002074 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002075 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002076 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002077 conn->link_mode &= ~HCI_LM_ENCRYPT;
2078 }
2079
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002080 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002081
Gustavo Padovana7d77232012-05-13 03:20:07 -03002082 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03002083 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
Gustavo Padovana7d77232012-05-13 03:20:07 -03002084 hci_conn_put(conn);
2085 goto unlock;
2086 }
2087
Marcel Holtmannf8558552008-07-14 20:13:49 +02002088 if (conn->state == BT_CONFIG) {
2089 if (!ev->status)
2090 conn->state = BT_CONNECTED;
2091
2092 hci_proto_connect_cfm(conn, ev->status);
2093 hci_conn_put(conn);
2094 } else
2095 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002096 }
2097
Gustavo Padovana7d77232012-05-13 03:20:07 -03002098unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002099 hci_dev_unlock(hdev);
2100}
2101
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002102static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2103 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002104{
2105 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2106 struct hci_conn *conn;
2107
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002108 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002109
2110 hci_dev_lock(hdev);
2111
2112 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2113 if (conn) {
2114 if (!ev->status)
2115 conn->link_mode |= HCI_LM_SECURE;
2116
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002117 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002118
2119 hci_key_change_cfm(conn, ev->status);
2120 }
2121
2122 hci_dev_unlock(hdev);
2123}
2124
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002125static void hci_remote_features_evt(struct hci_dev *hdev,
2126 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002127{
2128 struct hci_ev_remote_features *ev = (void *) skb->data;
2129 struct hci_conn *conn;
2130
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002131 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002132
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002133 hci_dev_lock(hdev);
2134
2135 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002136 if (!conn)
2137 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002138
Johan Hedbergccd556f2010-11-10 17:11:51 +02002139 if (!ev->status)
2140 memcpy(conn->features, ev->features, 8);
2141
2142 if (conn->state != BT_CONFIG)
2143 goto unlock;
2144
2145 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2146 struct hci_cp_read_remote_ext_features cp;
2147 cp.handle = ev->handle;
2148 cp.page = 0x01;
2149 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002150 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002151 goto unlock;
2152 }
2153
Johan Hedberg671267b2012-05-12 16:11:50 -03002154 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002155 struct hci_cp_remote_name_req cp;
2156 memset(&cp, 0, sizeof(cp));
2157 bacpy(&cp.bdaddr, &conn->dst);
2158 cp.pscan_rep_mode = 0x02;
2159 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002160 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2161 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002162 conn->dst_type, 0, NULL, 0,
2163 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002164
Johan Hedberg127178d2010-11-18 22:22:29 +02002165 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002166 conn->state = BT_CONNECTED;
2167 hci_proto_connect_cfm(conn, ev->status);
2168 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002169 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002170
Johan Hedbergccd556f2010-11-10 17:11:51 +02002171unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002172 hci_dev_unlock(hdev);
2173}
2174
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002175static void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002176{
2177 BT_DBG("%s", hdev->name);
2178}
2179
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002180static void hci_qos_setup_complete_evt(struct hci_dev *hdev,
2181 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002182{
2183 BT_DBG("%s", hdev->name);
2184}
2185
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002186static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002187{
2188 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002189 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002190 __u16 opcode;
2191
2192 skb_pull(skb, sizeof(*ev));
2193
2194 opcode = __le16_to_cpu(ev->opcode);
2195
2196 switch (opcode) {
2197 case HCI_OP_INQUIRY_CANCEL:
2198 hci_cc_inquiry_cancel(hdev, skb);
2199 break;
2200
Andre Guedes4d934832012-03-21 00:03:35 -03002201 case HCI_OP_PERIODIC_INQ:
2202 hci_cc_periodic_inq(hdev, skb);
2203 break;
2204
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002205 case HCI_OP_EXIT_PERIODIC_INQ:
2206 hci_cc_exit_periodic_inq(hdev, skb);
2207 break;
2208
2209 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2210 hci_cc_remote_name_req_cancel(hdev, skb);
2211 break;
2212
2213 case HCI_OP_ROLE_DISCOVERY:
2214 hci_cc_role_discovery(hdev, skb);
2215 break;
2216
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002217 case HCI_OP_READ_LINK_POLICY:
2218 hci_cc_read_link_policy(hdev, skb);
2219 break;
2220
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002221 case HCI_OP_WRITE_LINK_POLICY:
2222 hci_cc_write_link_policy(hdev, skb);
2223 break;
2224
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002225 case HCI_OP_READ_DEF_LINK_POLICY:
2226 hci_cc_read_def_link_policy(hdev, skb);
2227 break;
2228
2229 case HCI_OP_WRITE_DEF_LINK_POLICY:
2230 hci_cc_write_def_link_policy(hdev, skb);
2231 break;
2232
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002233 case HCI_OP_RESET:
2234 hci_cc_reset(hdev, skb);
2235 break;
2236
2237 case HCI_OP_WRITE_LOCAL_NAME:
2238 hci_cc_write_local_name(hdev, skb);
2239 break;
2240
2241 case HCI_OP_READ_LOCAL_NAME:
2242 hci_cc_read_local_name(hdev, skb);
2243 break;
2244
2245 case HCI_OP_WRITE_AUTH_ENABLE:
2246 hci_cc_write_auth_enable(hdev, skb);
2247 break;
2248
2249 case HCI_OP_WRITE_ENCRYPT_MODE:
2250 hci_cc_write_encrypt_mode(hdev, skb);
2251 break;
2252
2253 case HCI_OP_WRITE_SCAN_ENABLE:
2254 hci_cc_write_scan_enable(hdev, skb);
2255 break;
2256
2257 case HCI_OP_READ_CLASS_OF_DEV:
2258 hci_cc_read_class_of_dev(hdev, skb);
2259 break;
2260
2261 case HCI_OP_WRITE_CLASS_OF_DEV:
2262 hci_cc_write_class_of_dev(hdev, skb);
2263 break;
2264
2265 case HCI_OP_READ_VOICE_SETTING:
2266 hci_cc_read_voice_setting(hdev, skb);
2267 break;
2268
2269 case HCI_OP_WRITE_VOICE_SETTING:
2270 hci_cc_write_voice_setting(hdev, skb);
2271 break;
2272
2273 case HCI_OP_HOST_BUFFER_SIZE:
2274 hci_cc_host_buffer_size(hdev, skb);
2275 break;
2276
Marcel Holtmann333140b2008-07-14 20:13:48 +02002277 case HCI_OP_WRITE_SSP_MODE:
2278 hci_cc_write_ssp_mode(hdev, skb);
2279 break;
2280
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002281 case HCI_OP_READ_LOCAL_VERSION:
2282 hci_cc_read_local_version(hdev, skb);
2283 break;
2284
2285 case HCI_OP_READ_LOCAL_COMMANDS:
2286 hci_cc_read_local_commands(hdev, skb);
2287 break;
2288
2289 case HCI_OP_READ_LOCAL_FEATURES:
2290 hci_cc_read_local_features(hdev, skb);
2291 break;
2292
Andre Guedes971e3a42011-06-30 19:20:52 -03002293 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2294 hci_cc_read_local_ext_features(hdev, skb);
2295 break;
2296
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002297 case HCI_OP_READ_BUFFER_SIZE:
2298 hci_cc_read_buffer_size(hdev, skb);
2299 break;
2300
2301 case HCI_OP_READ_BD_ADDR:
2302 hci_cc_read_bd_addr(hdev, skb);
2303 break;
2304
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002305 case HCI_OP_READ_DATA_BLOCK_SIZE:
2306 hci_cc_read_data_block_size(hdev, skb);
2307 break;
2308
Johan Hedberg23bb5762010-12-21 23:01:27 +02002309 case HCI_OP_WRITE_CA_TIMEOUT:
2310 hci_cc_write_ca_timeout(hdev, skb);
2311 break;
2312
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002313 case HCI_OP_READ_FLOW_CONTROL_MODE:
2314 hci_cc_read_flow_control_mode(hdev, skb);
2315 break;
2316
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002317 case HCI_OP_READ_LOCAL_AMP_INFO:
2318 hci_cc_read_local_amp_info(hdev, skb);
2319 break;
2320
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002321 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2322 hci_cc_read_local_amp_assoc(hdev, skb);
2323 break;
2324
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002325 case HCI_OP_DELETE_STORED_LINK_KEY:
2326 hci_cc_delete_stored_link_key(hdev, skb);
2327 break;
2328
Johan Hedbergd5859e22011-01-25 01:19:58 +02002329 case HCI_OP_SET_EVENT_MASK:
2330 hci_cc_set_event_mask(hdev, skb);
2331 break;
2332
2333 case HCI_OP_WRITE_INQUIRY_MODE:
2334 hci_cc_write_inquiry_mode(hdev, skb);
2335 break;
2336
2337 case HCI_OP_READ_INQ_RSP_TX_POWER:
2338 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2339 break;
2340
2341 case HCI_OP_SET_EVENT_FLT:
2342 hci_cc_set_event_flt(hdev, skb);
2343 break;
2344
Johan Hedberg980e1a52011-01-22 06:10:07 +02002345 case HCI_OP_PIN_CODE_REPLY:
2346 hci_cc_pin_code_reply(hdev, skb);
2347 break;
2348
2349 case HCI_OP_PIN_CODE_NEG_REPLY:
2350 hci_cc_pin_code_neg_reply(hdev, skb);
2351 break;
2352
Szymon Jancc35938b2011-03-22 13:12:21 +01002353 case HCI_OP_READ_LOCAL_OOB_DATA:
2354 hci_cc_read_local_oob_data_reply(hdev, skb);
2355 break;
2356
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002357 case HCI_OP_LE_READ_BUFFER_SIZE:
2358 hci_cc_le_read_buffer_size(hdev, skb);
2359 break;
2360
Johan Hedberg60e77322013-01-22 14:01:59 +02002361 case HCI_OP_LE_READ_LOCAL_FEATURES:
2362 hci_cc_le_read_local_features(hdev, skb);
2363 break;
2364
Johan Hedberg8fa19092012-10-19 20:57:49 +03002365 case HCI_OP_LE_READ_ADV_TX_POWER:
2366 hci_cc_le_read_adv_tx_power(hdev, skb);
2367 break;
2368
Johan Hedberge36b04c2012-10-19 20:57:47 +03002369 case HCI_OP_LE_SET_EVENT_MASK:
2370 hci_cc_le_set_event_mask(hdev, skb);
2371 break;
2372
Johan Hedberga5c29682011-02-19 12:05:57 -03002373 case HCI_OP_USER_CONFIRM_REPLY:
2374 hci_cc_user_confirm_reply(hdev, skb);
2375 break;
2376
2377 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2378 hci_cc_user_confirm_neg_reply(hdev, skb);
2379 break;
2380
Brian Gix1143d452011-11-23 08:28:34 -08002381 case HCI_OP_USER_PASSKEY_REPLY:
2382 hci_cc_user_passkey_reply(hdev, skb);
2383 break;
2384
2385 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2386 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002387 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002388
2389 case HCI_OP_LE_SET_SCAN_PARAM:
2390 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002391 break;
2392
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002393 case HCI_OP_LE_SET_ADV_ENABLE:
2394 hci_cc_le_set_adv_enable(hdev, skb);
2395 break;
2396
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002397 case HCI_OP_LE_SET_SCAN_ENABLE:
2398 hci_cc_le_set_scan_enable(hdev, skb);
2399 break;
2400
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002401 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2402 hci_cc_le_read_white_list_size(hdev, skb);
2403 break;
2404
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002405 case HCI_OP_LE_LTK_REPLY:
2406 hci_cc_le_ltk_reply(hdev, skb);
2407 break;
2408
2409 case HCI_OP_LE_LTK_NEG_REPLY:
2410 hci_cc_le_ltk_neg_reply(hdev, skb);
2411 break;
2412
Johan Hedberg9b008c02013-01-22 14:02:01 +02002413 case HCI_OP_LE_READ_SUPPORTED_STATES:
2414 hci_cc_le_read_supported_states(hdev, skb);
2415 break;
2416
Andre Guedesf9b49302011-06-30 19:20:53 -03002417 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2418 hci_cc_write_le_host_supported(hdev, skb);
2419 break;
2420
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002421 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2422 hci_cc_write_remote_amp_assoc(hdev, skb);
2423 break;
2424
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002425 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002426 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002427 break;
2428 }
2429
Ville Tervo6bd32322011-02-16 16:32:41 +02002430 if (ev->opcode != HCI_OP_NOP)
2431 del_timer(&hdev->cmd_timer);
2432
Johan Hedberg9238f362013-03-05 20:37:48 +02002433 hci_req_cmd_complete(hdev, ev->opcode, status);
2434
Szymon Jancdbccd792012-12-11 08:51:19 +01002435 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002436 atomic_set(&hdev->cmd_cnt, 1);
2437 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002438 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002439 }
2440}
2441
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002442static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002443{
2444 struct hci_ev_cmd_status *ev = (void *) skb->data;
2445 __u16 opcode;
2446
2447 skb_pull(skb, sizeof(*ev));
2448
2449 opcode = __le16_to_cpu(ev->opcode);
2450
2451 switch (opcode) {
2452 case HCI_OP_INQUIRY:
2453 hci_cs_inquiry(hdev, ev->status);
2454 break;
2455
2456 case HCI_OP_CREATE_CONN:
2457 hci_cs_create_conn(hdev, ev->status);
2458 break;
2459
2460 case HCI_OP_ADD_SCO:
2461 hci_cs_add_sco(hdev, ev->status);
2462 break;
2463
Marcel Holtmannf8558552008-07-14 20:13:49 +02002464 case HCI_OP_AUTH_REQUESTED:
2465 hci_cs_auth_requested(hdev, ev->status);
2466 break;
2467
2468 case HCI_OP_SET_CONN_ENCRYPT:
2469 hci_cs_set_conn_encrypt(hdev, ev->status);
2470 break;
2471
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002472 case HCI_OP_REMOTE_NAME_REQ:
2473 hci_cs_remote_name_req(hdev, ev->status);
2474 break;
2475
Marcel Holtmann769be972008-07-14 20:13:49 +02002476 case HCI_OP_READ_REMOTE_FEATURES:
2477 hci_cs_read_remote_features(hdev, ev->status);
2478 break;
2479
2480 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2481 hci_cs_read_remote_ext_features(hdev, ev->status);
2482 break;
2483
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002484 case HCI_OP_SETUP_SYNC_CONN:
2485 hci_cs_setup_sync_conn(hdev, ev->status);
2486 break;
2487
2488 case HCI_OP_SNIFF_MODE:
2489 hci_cs_sniff_mode(hdev, ev->status);
2490 break;
2491
2492 case HCI_OP_EXIT_SNIFF_MODE:
2493 hci_cs_exit_sniff_mode(hdev, ev->status);
2494 break;
2495
Johan Hedberg8962ee72011-01-20 12:40:27 +02002496 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002497 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002498 break;
2499
Ville Tervofcd89c02011-02-10 22:38:47 -03002500 case HCI_OP_LE_CREATE_CONN:
2501 hci_cs_le_create_conn(hdev, ev->status);
2502 break;
2503
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002504 case HCI_OP_LE_START_ENC:
2505 hci_cs_le_start_enc(hdev, ev->status);
2506 break;
2507
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002508 case HCI_OP_CREATE_PHY_LINK:
2509 hci_cs_create_phylink(hdev, ev->status);
2510 break;
2511
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002512 case HCI_OP_ACCEPT_PHY_LINK:
2513 hci_cs_accept_phylink(hdev, ev->status);
2514 break;
2515
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02002516 case HCI_OP_CREATE_LOGICAL_LINK:
2517 hci_cs_create_logical_link(hdev, ev->status);
2518 break;
2519
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002520 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002521 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002522 break;
2523 }
2524
Ville Tervo6bd32322011-02-16 16:32:41 +02002525 if (ev->opcode != HCI_OP_NOP)
2526 del_timer(&hdev->cmd_timer);
2527
Johan Hedberg9238f362013-03-05 20:37:48 +02002528 hci_req_cmd_status(hdev, ev->opcode, ev->status);
2529
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002530 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002531 atomic_set(&hdev->cmd_cnt, 1);
2532 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002533 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002534 }
2535}
2536
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002537static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002538{
2539 struct hci_ev_role_change *ev = (void *) skb->data;
2540 struct hci_conn *conn;
2541
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002542 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002543
2544 hci_dev_lock(hdev);
2545
2546 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2547 if (conn) {
2548 if (!ev->status) {
2549 if (ev->role)
2550 conn->link_mode &= ~HCI_LM_MASTER;
2551 else
2552 conn->link_mode |= HCI_LM_MASTER;
2553 }
2554
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002555 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002556
2557 hci_role_switch_cfm(conn, ev->status, ev->role);
2558 }
2559
2560 hci_dev_unlock(hdev);
2561}
2562
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002563static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002565 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566 int i;
2567
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002568 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2569 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2570 return;
2571 }
2572
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002573 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002574 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575 BT_DBG("%s bad parameters", hdev->name);
2576 return;
2577 }
2578
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002579 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2580
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002581 for (i = 0; i < ev->num_hndl; i++) {
2582 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583 struct hci_conn *conn;
2584 __u16 handle, count;
2585
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002586 handle = __le16_to_cpu(info->handle);
2587 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002588
2589 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002590 if (!conn)
2591 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002593 conn->sent -= count;
2594
2595 switch (conn->type) {
2596 case ACL_LINK:
2597 hdev->acl_cnt += count;
2598 if (hdev->acl_cnt > hdev->acl_pkts)
2599 hdev->acl_cnt = hdev->acl_pkts;
2600 break;
2601
2602 case LE_LINK:
2603 if (hdev->le_pkts) {
2604 hdev->le_cnt += count;
2605 if (hdev->le_cnt > hdev->le_pkts)
2606 hdev->le_cnt = hdev->le_pkts;
2607 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002608 hdev->acl_cnt += count;
2609 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002610 hdev->acl_cnt = hdev->acl_pkts;
2611 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002612 break;
2613
2614 case SCO_LINK:
2615 hdev->sco_cnt += count;
2616 if (hdev->sco_cnt > hdev->sco_pkts)
2617 hdev->sco_cnt = hdev->sco_pkts;
2618 break;
2619
2620 default:
2621 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2622 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002623 }
2624 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002625
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002626 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627}
2628
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002629static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2630 __u16 handle)
2631{
2632 struct hci_chan *chan;
2633
2634 switch (hdev->dev_type) {
2635 case HCI_BREDR:
2636 return hci_conn_hash_lookup_handle(hdev, handle);
2637 case HCI_AMP:
2638 chan = hci_chan_lookup_handle(hdev, handle);
2639 if (chan)
2640 return chan->conn;
2641 break;
2642 default:
2643 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2644 break;
2645 }
2646
2647 return NULL;
2648}
2649
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002650static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002651{
2652 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2653 int i;
2654
2655 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2656 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2657 return;
2658 }
2659
2660 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002661 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002662 BT_DBG("%s bad parameters", hdev->name);
2663 return;
2664 }
2665
2666 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002667 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002668
2669 for (i = 0; i < ev->num_hndl; i++) {
2670 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002671 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002672 __u16 handle, block_count;
2673
2674 handle = __le16_to_cpu(info->handle);
2675 block_count = __le16_to_cpu(info->blocks);
2676
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002677 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002678 if (!conn)
2679 continue;
2680
2681 conn->sent -= block_count;
2682
2683 switch (conn->type) {
2684 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002685 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002686 hdev->block_cnt += block_count;
2687 if (hdev->block_cnt > hdev->num_blocks)
2688 hdev->block_cnt = hdev->num_blocks;
2689 break;
2690
2691 default:
2692 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2693 break;
2694 }
2695 }
2696
2697 queue_work(hdev->workqueue, &hdev->tx_work);
2698}
2699
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002700static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002701{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002702 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002703 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002705 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706
2707 hci_dev_lock(hdev);
2708
Marcel Holtmann04837f62006-07-03 10:02:33 +02002709 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2710 if (conn) {
2711 conn->mode = ev->mode;
2712 conn->interval = __le16_to_cpu(ev->interval);
2713
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002714 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2715 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002716 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002717 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002718 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002719 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002720 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002721
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002722 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002723 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002724 }
2725
2726 hci_dev_unlock(hdev);
2727}
2728
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002729static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002731 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2732 struct hci_conn *conn;
2733
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002734 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002735
2736 hci_dev_lock(hdev);
2737
2738 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002739 if (!conn)
2740 goto unlock;
2741
2742 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002743 hci_conn_hold(conn);
2744 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2745 hci_conn_put(conn);
2746 }
2747
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002748 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002749 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002750 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002751 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002752 u8 secure;
2753
2754 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2755 secure = 1;
2756 else
2757 secure = 0;
2758
Johan Hedberg744cf192011-11-08 20:40:14 +02002759 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002760 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002761
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002762unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002763 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002764}
2765
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002766static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002768 struct hci_ev_link_key_req *ev = (void *) skb->data;
2769 struct hci_cp_link_key_reply cp;
2770 struct hci_conn *conn;
2771 struct link_key *key;
2772
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002773 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002774
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002775 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002776 return;
2777
2778 hci_dev_lock(hdev);
2779
2780 key = hci_find_link_key(hdev, &ev->bdaddr);
2781 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002782 BT_DBG("%s link key not found for %pMR", hdev->name,
2783 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002784 goto not_found;
2785 }
2786
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002787 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2788 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002789
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002790 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002791 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002792 BT_DBG("%s ignoring debug key", hdev->name);
2793 goto not_found;
2794 }
2795
2796 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002797 if (conn) {
2798 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002799 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002800 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2801 goto not_found;
2802 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002803
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002804 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002805 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002806 BT_DBG("%s ignoring key unauthenticated for high security",
2807 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002808 goto not_found;
2809 }
2810
2811 conn->key_type = key->type;
2812 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002813 }
2814
2815 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002816 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002817
2818 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2819
2820 hci_dev_unlock(hdev);
2821
2822 return;
2823
2824not_found:
2825 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2826 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827}
2828
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002829static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002831 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2832 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002833 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002834
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002835 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002836
2837 hci_dev_lock(hdev);
2838
2839 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2840 if (conn) {
2841 hci_conn_hold(conn);
2842 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002843 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002844
2845 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2846 conn->key_type = ev->key_type;
2847
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002848 hci_conn_put(conn);
2849 }
2850
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002851 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002852 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002853 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002854
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002855 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856}
2857
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002858static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002859{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002860 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002861 struct hci_conn *conn;
2862
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002863 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002864
2865 hci_dev_lock(hdev);
2866
2867 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868 if (conn && !ev->status) {
2869 struct inquiry_entry *ie;
2870
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002871 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2872 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002873 ie->data.clock_offset = ev->clock_offset;
2874 ie->timestamp = jiffies;
2875 }
2876 }
2877
2878 hci_dev_unlock(hdev);
2879}
2880
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002881static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002882{
2883 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2884 struct hci_conn *conn;
2885
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002886 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002887
2888 hci_dev_lock(hdev);
2889
2890 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2891 if (conn && !ev->status)
2892 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2893
2894 hci_dev_unlock(hdev);
2895}
2896
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002897static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002898{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002899 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002900 struct inquiry_entry *ie;
2901
2902 BT_DBG("%s", hdev->name);
2903
2904 hci_dev_lock(hdev);
2905
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002906 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2907 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002908 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2909 ie->timestamp = jiffies;
2910 }
2911
2912 hci_dev_unlock(hdev);
2913}
2914
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002915static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2916 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002917{
2918 struct inquiry_data data;
2919 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002920 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002921
2922 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2923
2924 if (!num_rsp)
2925 return;
2926
Andre Guedes1519cc12012-03-21 00:03:38 -03002927 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2928 return;
2929
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002930 hci_dev_lock(hdev);
2931
2932 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002933 struct inquiry_info_with_rssi_and_pscan_mode *info;
2934 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002935
Johan Hedberge17acd42011-03-30 23:57:16 +03002936 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002937 bacpy(&data.bdaddr, &info->bdaddr);
2938 data.pscan_rep_mode = info->pscan_rep_mode;
2939 data.pscan_period_mode = info->pscan_period_mode;
2940 data.pscan_mode = info->pscan_mode;
2941 memcpy(data.dev_class, info->dev_class, 3);
2942 data.clock_offset = info->clock_offset;
2943 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002944 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002945
2946 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002947 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002948 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002949 info->dev_class, info->rssi,
2950 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002951 }
2952 } else {
2953 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2954
Johan Hedberge17acd42011-03-30 23:57:16 +03002955 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002956 bacpy(&data.bdaddr, &info->bdaddr);
2957 data.pscan_rep_mode = info->pscan_rep_mode;
2958 data.pscan_period_mode = info->pscan_period_mode;
2959 data.pscan_mode = 0x00;
2960 memcpy(data.dev_class, info->dev_class, 3);
2961 data.clock_offset = info->clock_offset;
2962 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002963 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002964 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002965 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002966 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002967 info->dev_class, info->rssi,
2968 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002969 }
2970 }
2971
2972 hci_dev_unlock(hdev);
2973}
2974
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002975static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2976 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002977{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002978 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2979 struct hci_conn *conn;
2980
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002981 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002982
Marcel Holtmann41a96212008-07-14 20:13:48 +02002983 hci_dev_lock(hdev);
2984
2985 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002986 if (!conn)
2987 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002988
Johan Hedbergccd556f2010-11-10 17:11:51 +02002989 if (!ev->status && ev->page == 0x01) {
2990 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002991
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002992 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2993 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002994 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002995
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002996 if (ev->features[0] & LMP_HOST_SSP)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002997 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002998 }
2999
Johan Hedbergccd556f2010-11-10 17:11:51 +02003000 if (conn->state != BT_CONFIG)
3001 goto unlock;
3002
Johan Hedberg671267b2012-05-12 16:11:50 -03003003 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02003004 struct hci_cp_remote_name_req cp;
3005 memset(&cp, 0, sizeof(cp));
3006 bacpy(&cp.bdaddr, &conn->dst);
3007 cp.pscan_rep_mode = 0x02;
3008 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02003009 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3010 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003011 conn->dst_type, 0, NULL, 0,
3012 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02003013
Johan Hedberg127178d2010-11-18 22:22:29 +02003014 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02003015 conn->state = BT_CONNECTED;
3016 hci_proto_connect_cfm(conn, ev->status);
3017 hci_conn_put(conn);
3018 }
3019
3020unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02003021 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003022}
3023
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003024static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3025 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003026{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003027 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3028 struct hci_conn *conn;
3029
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003030 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003031
3032 hci_dev_lock(hdev);
3033
3034 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02003035 if (!conn) {
3036 if (ev->link_type == ESCO_LINK)
3037 goto unlock;
3038
3039 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3040 if (!conn)
3041 goto unlock;
3042
3043 conn->type = SCO_LINK;
3044 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003045
Marcel Holtmann732547f2009-04-19 19:14:14 +02003046 switch (ev->status) {
3047 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003048 conn->handle = __le16_to_cpu(ev->handle);
3049 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003050
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07003051 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003052 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02003053 break;
3054
Stephen Coe705e5712010-02-16 11:29:44 -05003055 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003056 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08003057 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003058 case 0x1f: /* Unspecified error */
3059 if (conn->out && conn->attempt < 2) {
3060 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3061 (hdev->esco_type & EDR_ESCO_MASK);
3062 hci_setup_sync(conn, conn->link->handle);
3063 goto unlock;
3064 }
3065 /* fall through */
3066
3067 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003068 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003069 break;
3070 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003071
3072 hci_proto_connect_cfm(conn, ev->status);
3073 if (ev->status)
3074 hci_conn_del(conn);
3075
3076unlock:
3077 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003078}
3079
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003080static void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003081{
3082 BT_DBG("%s", hdev->name);
3083}
3084
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003085static void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02003086{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003087 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02003088
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003089 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02003090}
3091
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003092static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3093 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003094{
3095 struct inquiry_data data;
3096 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3097 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303098 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003099
3100 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3101
3102 if (!num_rsp)
3103 return;
3104
Andre Guedes1519cc12012-03-21 00:03:38 -03003105 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3106 return;
3107
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003108 hci_dev_lock(hdev);
3109
Johan Hedberge17acd42011-03-30 23:57:16 +03003110 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003111 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003112
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003113 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003114 data.pscan_rep_mode = info->pscan_rep_mode;
3115 data.pscan_period_mode = info->pscan_period_mode;
3116 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003117 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003118 data.clock_offset = info->clock_offset;
3119 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003120 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003121
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003122 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003123 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003124 sizeof(info->data),
3125 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003126 else
3127 name_known = true;
3128
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003129 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003130 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303131 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003132 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003133 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303134 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003135 }
3136
3137 hci_dev_unlock(hdev);
3138}
3139
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003140static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3141 struct sk_buff *skb)
3142{
3143 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3144 struct hci_conn *conn;
3145
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003146 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003147 __le16_to_cpu(ev->handle));
3148
3149 hci_dev_lock(hdev);
3150
3151 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3152 if (!conn)
3153 goto unlock;
3154
3155 if (!ev->status)
3156 conn->sec_level = conn->pending_sec_level;
3157
3158 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3159
3160 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003161 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003162 hci_conn_put(conn);
3163 goto unlock;
3164 }
3165
3166 if (conn->state == BT_CONFIG) {
3167 if (!ev->status)
3168 conn->state = BT_CONNECTED;
3169
3170 hci_proto_connect_cfm(conn, ev->status);
3171 hci_conn_put(conn);
3172 } else {
3173 hci_auth_cfm(conn, ev->status);
3174
3175 hci_conn_hold(conn);
3176 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
3177 hci_conn_put(conn);
3178 }
3179
3180unlock:
3181 hci_dev_unlock(hdev);
3182}
3183
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003184static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003185{
3186 /* If remote requests dedicated bonding follow that lead */
3187 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3188 /* If both remote and local IO capabilities allow MITM
3189 * protection then require it, otherwise don't */
3190 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3191 return 0x02;
3192 else
3193 return 0x03;
3194 }
3195
3196 /* If remote requests no-bonding follow that lead */
3197 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003198 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003199
3200 return conn->auth_type;
3201}
3202
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003203static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003204{
3205 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3206 struct hci_conn *conn;
3207
3208 BT_DBG("%s", hdev->name);
3209
3210 hci_dev_lock(hdev);
3211
3212 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003213 if (!conn)
3214 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003215
Johan Hedberg03b555e2011-01-04 15:40:05 +02003216 hci_conn_hold(conn);
3217
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003218 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003219 goto unlock;
3220
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003221 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003222 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003223 struct hci_cp_io_capability_reply cp;
3224
3225 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303226 /* Change the IO capability from KeyboardDisplay
3227 * to DisplayYesNo as it is not supported by BT spec. */
3228 cp.capability = (conn->io_capability == 0x04) ?
3229 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003230 conn->auth_type = hci_get_auth_req(conn);
3231 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003232
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003233 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3234 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003235 cp.oob_data = 0x01;
3236 else
3237 cp.oob_data = 0x00;
3238
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003239 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003240 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003241 } else {
3242 struct hci_cp_io_capability_neg_reply cp;
3243
3244 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003245 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003246
3247 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003248 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003249 }
3250
3251unlock:
3252 hci_dev_unlock(hdev);
3253}
3254
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003255static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003256{
3257 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3258 struct hci_conn *conn;
3259
3260 BT_DBG("%s", hdev->name);
3261
3262 hci_dev_lock(hdev);
3263
3264 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3265 if (!conn)
3266 goto unlock;
3267
Johan Hedberg03b555e2011-01-04 15:40:05 +02003268 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003269 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003270 if (ev->oob_data)
3271 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003272
3273unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003274 hci_dev_unlock(hdev);
3275}
3276
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003277static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3278 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003279{
3280 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003281 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003282 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003283
3284 BT_DBG("%s", hdev->name);
3285
3286 hci_dev_lock(hdev);
3287
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003288 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003289 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003290
Johan Hedberg7a828902011-04-28 11:28:53 -07003291 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3292 if (!conn)
3293 goto unlock;
3294
3295 loc_mitm = (conn->auth_type & 0x01);
3296 rem_mitm = (conn->remote_auth & 0x01);
3297
3298 /* If we require MITM but the remote device can't provide that
3299 * (it has NoInputNoOutput) then reject the confirmation
3300 * request. The only exception is when we're dedicated bonding
3301 * initiators (connect_cfm_cb set) since then we always have the MITM
3302 * bit set. */
3303 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3304 BT_DBG("Rejecting request: remote device can't provide MITM");
3305 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003306 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003307 goto unlock;
3308 }
3309
3310 /* If no side requires MITM protection; auto-accept */
3311 if ((!loc_mitm || conn->remote_cap == 0x03) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003312 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003313
3314 /* If we're not the initiators request authorization to
3315 * proceed from user space (mgmt_user_confirm with
3316 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003317 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003318 BT_DBG("Confirming auto-accept as acceptor");
3319 confirm_hint = 1;
3320 goto confirm;
3321 }
3322
Johan Hedberg9f616562011-04-28 11:28:54 -07003323 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003324 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003325
3326 if (hdev->auto_accept_delay > 0) {
3327 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3328 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3329 goto unlock;
3330 }
3331
Johan Hedberg7a828902011-04-28 11:28:53 -07003332 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003333 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003334 goto unlock;
3335 }
3336
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003337confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003338 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003339 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003340
3341unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003342 hci_dev_unlock(hdev);
3343}
3344
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003345static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3346 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003347{
3348 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3349
3350 BT_DBG("%s", hdev->name);
3351
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003352 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003353 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003354}
3355
Johan Hedberg92a25252012-09-06 18:39:26 +03003356static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3357 struct sk_buff *skb)
3358{
3359 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3360 struct hci_conn *conn;
3361
3362 BT_DBG("%s", hdev->name);
3363
3364 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3365 if (!conn)
3366 return;
3367
3368 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3369 conn->passkey_entered = 0;
3370
3371 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3372 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3373 conn->dst_type, conn->passkey_notify,
3374 conn->passkey_entered);
3375}
3376
3377static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3378{
3379 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3380 struct hci_conn *conn;
3381
3382 BT_DBG("%s", hdev->name);
3383
3384 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3385 if (!conn)
3386 return;
3387
3388 switch (ev->type) {
3389 case HCI_KEYPRESS_STARTED:
3390 conn->passkey_entered = 0;
3391 return;
3392
3393 case HCI_KEYPRESS_ENTERED:
3394 conn->passkey_entered++;
3395 break;
3396
3397 case HCI_KEYPRESS_ERASED:
3398 conn->passkey_entered--;
3399 break;
3400
3401 case HCI_KEYPRESS_CLEARED:
3402 conn->passkey_entered = 0;
3403 break;
3404
3405 case HCI_KEYPRESS_COMPLETED:
3406 return;
3407 }
3408
3409 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3410 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3411 conn->dst_type, conn->passkey_notify,
3412 conn->passkey_entered);
3413}
3414
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003415static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3416 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003417{
3418 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3419 struct hci_conn *conn;
3420
3421 BT_DBG("%s", hdev->name);
3422
3423 hci_dev_lock(hdev);
3424
3425 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003426 if (!conn)
3427 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003428
Johan Hedberg2a611692011-02-19 12:06:00 -03003429 /* To avoid duplicate auth_failed events to user space we check
3430 * the HCI_CONN_AUTH_PEND flag which will be set if we
3431 * initiated the authentication. A traditional auth_complete
3432 * event gets always produced as initiator and is also mapped to
3433 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003434 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003435 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003436 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003437
3438 hci_conn_put(conn);
3439
3440unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003441 hci_dev_unlock(hdev);
3442}
3443
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003444static void hci_remote_host_features_evt(struct hci_dev *hdev,
3445 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003446{
3447 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3448 struct inquiry_entry *ie;
3449
3450 BT_DBG("%s", hdev->name);
3451
3452 hci_dev_lock(hdev);
3453
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003454 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3455 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003456 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003457
3458 hci_dev_unlock(hdev);
3459}
3460
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003461static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3462 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003463{
3464 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3465 struct oob_data *data;
3466
3467 BT_DBG("%s", hdev->name);
3468
3469 hci_dev_lock(hdev);
3470
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003471 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003472 goto unlock;
3473
Szymon Janc2763eda2011-03-22 13:12:22 +01003474 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3475 if (data) {
3476 struct hci_cp_remote_oob_data_reply cp;
3477
3478 bacpy(&cp.bdaddr, &ev->bdaddr);
3479 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3480 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3481
3482 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003483 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003484 } else {
3485 struct hci_cp_remote_oob_data_neg_reply cp;
3486
3487 bacpy(&cp.bdaddr, &ev->bdaddr);
3488 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003489 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003490 }
3491
Szymon Jance1ba1f12011-04-06 13:01:59 +02003492unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003493 hci_dev_unlock(hdev);
3494}
3495
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003496static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3497 struct sk_buff *skb)
3498{
3499 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3500 struct hci_conn *hcon, *bredr_hcon;
3501
3502 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3503 ev->status);
3504
3505 hci_dev_lock(hdev);
3506
3507 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3508 if (!hcon) {
3509 hci_dev_unlock(hdev);
3510 return;
3511 }
3512
3513 if (ev->status) {
3514 hci_conn_del(hcon);
3515 hci_dev_unlock(hdev);
3516 return;
3517 }
3518
3519 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3520
3521 hcon->state = BT_CONNECTED;
3522 bacpy(&hcon->dst, &bredr_hcon->dst);
3523
3524 hci_conn_hold(hcon);
3525 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3526 hci_conn_put(hcon);
3527
3528 hci_conn_hold_device(hcon);
3529 hci_conn_add_sysfs(hcon);
3530
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003531 amp_physical_cfm(bredr_hcon, hcon);
3532
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003533 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003534}
3535
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003536static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3537{
3538 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3539 struct hci_conn *hcon;
3540 struct hci_chan *hchan;
3541 struct amp_mgr *mgr;
3542
3543 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3544 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3545 ev->status);
3546
3547 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3548 if (!hcon)
3549 return;
3550
3551 /* Create AMP hchan */
3552 hchan = hci_chan_create(hcon);
3553 if (!hchan)
3554 return;
3555
3556 hchan->handle = le16_to_cpu(ev->handle);
3557
3558 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3559
3560 mgr = hcon->amp_mgr;
3561 if (mgr && mgr->bredr_chan) {
3562 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3563
3564 l2cap_chan_lock(bredr_chan);
3565
3566 bredr_chan->conn->mtu = hdev->block_mtu;
3567 l2cap_logical_cfm(bredr_chan, hchan, 0);
3568 hci_conn_hold(hcon);
3569
3570 l2cap_chan_unlock(bredr_chan);
3571 }
3572}
3573
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003574static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3575 struct sk_buff *skb)
3576{
3577 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3578 struct hci_chan *hchan;
3579
3580 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3581 le16_to_cpu(ev->handle), ev->status);
3582
3583 if (ev->status)
3584 return;
3585
3586 hci_dev_lock(hdev);
3587
3588 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3589 if (!hchan)
3590 goto unlock;
3591
3592 amp_destroy_logical_link(hchan, ev->reason);
3593
3594unlock:
3595 hci_dev_unlock(hdev);
3596}
3597
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003598static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3599 struct sk_buff *skb)
3600{
3601 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3602 struct hci_conn *hcon;
3603
3604 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3605
3606 if (ev->status)
3607 return;
3608
3609 hci_dev_lock(hdev);
3610
3611 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3612 if (hcon) {
3613 hcon->state = BT_CLOSED;
3614 hci_conn_del(hcon);
3615 }
3616
3617 hci_dev_unlock(hdev);
3618}
3619
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003620static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003621{
3622 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3623 struct hci_conn *conn;
3624
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003625 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003626
3627 hci_dev_lock(hdev);
3628
Andre Guedesb47a09b2012-07-27 15:10:15 -03003629 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003630 if (!conn) {
3631 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3632 if (!conn) {
3633 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003634 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003635 }
Andre Guedes29b79882011-05-31 14:20:54 -03003636
3637 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003638
3639 if (ev->role == LE_CONN_ROLE_MASTER) {
3640 conn->out = true;
3641 conn->link_mode |= HCI_LM_MASTER;
3642 }
Ville Tervob62f3282011-02-10 22:38:50 -03003643 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003644
Andre Guedescd17dec2012-07-27 15:10:16 -03003645 if (ev->status) {
3646 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3647 conn->dst_type, ev->status);
3648 hci_proto_connect_cfm(conn, ev->status);
3649 conn->state = BT_CLOSED;
3650 hci_conn_del(conn);
3651 goto unlock;
3652 }
3653
Johan Hedbergb644ba32012-01-17 21:48:47 +02003654 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3655 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003656 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003657
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003658 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003659 conn->handle = __le16_to_cpu(ev->handle);
3660 conn->state = BT_CONNECTED;
3661
3662 hci_conn_hold_device(conn);
3663 hci_conn_add_sysfs(conn);
3664
3665 hci_proto_connect_cfm(conn, ev->status);
3666
3667unlock:
3668 hci_dev_unlock(hdev);
3669}
3670
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003671static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003672{
Andre Guedese95beb42011-09-26 20:48:35 -03003673 u8 num_reports = skb->data[0];
3674 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003675 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003676
Andre Guedese95beb42011-09-26 20:48:35 -03003677 while (num_reports--) {
3678 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003679
Andre Guedes3c9e9192012-01-10 18:20:50 -03003680 rssi = ev->data[ev->length];
3681 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003682 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003683
Andre Guedese95beb42011-09-26 20:48:35 -03003684 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003685 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003686}
3687
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003688static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003689{
3690 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3691 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003692 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003693 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003694 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003695
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003696 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003697
3698 hci_dev_lock(hdev);
3699
3700 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003701 if (conn == NULL)
3702 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003703
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003704 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3705 if (ltk == NULL)
3706 goto not_found;
3707
3708 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003709 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003710
3711 if (ltk->authenticated)
3712 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003713
3714 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3715
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003716 if (ltk->type & HCI_SMP_STK) {
3717 list_del(&ltk->list);
3718 kfree(ltk);
3719 }
3720
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003721 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003722
3723 return;
3724
3725not_found:
3726 neg.handle = ev->handle;
3727 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3728 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003729}
3730
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003731static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003732{
3733 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3734
3735 skb_pull(skb, sizeof(*le_ev));
3736
3737 switch (le_ev->subevent) {
3738 case HCI_EV_LE_CONN_COMPLETE:
3739 hci_le_conn_complete_evt(hdev, skb);
3740 break;
3741
Andre Guedes9aa04c92011-05-26 16:23:51 -03003742 case HCI_EV_LE_ADVERTISING_REPORT:
3743 hci_le_adv_report_evt(hdev, skb);
3744 break;
3745
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003746 case HCI_EV_LE_LTK_REQ:
3747 hci_le_ltk_request_evt(hdev, skb);
3748 break;
3749
Ville Tervofcd89c02011-02-10 22:38:47 -03003750 default:
3751 break;
3752 }
3753}
3754
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003755static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3756{
3757 struct hci_ev_channel_selected *ev = (void *) skb->data;
3758 struct hci_conn *hcon;
3759
3760 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3761
3762 skb_pull(skb, sizeof(*ev));
3763
3764 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3765 if (!hcon)
3766 return;
3767
3768 amp_read_loc_assoc_final_data(hdev, hcon);
3769}
3770
Linus Torvalds1da177e2005-04-16 15:20:36 -07003771void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3772{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003773 struct hci_event_hdr *hdr = (void *) skb->data;
3774 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003775
3776 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3777
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003778 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003779 case HCI_EV_INQUIRY_COMPLETE:
3780 hci_inquiry_complete_evt(hdev, skb);
3781 break;
3782
3783 case HCI_EV_INQUIRY_RESULT:
3784 hci_inquiry_result_evt(hdev, skb);
3785 break;
3786
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003787 case HCI_EV_CONN_COMPLETE:
3788 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003789 break;
3790
Linus Torvalds1da177e2005-04-16 15:20:36 -07003791 case HCI_EV_CONN_REQUEST:
3792 hci_conn_request_evt(hdev, skb);
3793 break;
3794
Linus Torvalds1da177e2005-04-16 15:20:36 -07003795 case HCI_EV_DISCONN_COMPLETE:
3796 hci_disconn_complete_evt(hdev, skb);
3797 break;
3798
Linus Torvalds1da177e2005-04-16 15:20:36 -07003799 case HCI_EV_AUTH_COMPLETE:
3800 hci_auth_complete_evt(hdev, skb);
3801 break;
3802
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003803 case HCI_EV_REMOTE_NAME:
3804 hci_remote_name_evt(hdev, skb);
3805 break;
3806
Linus Torvalds1da177e2005-04-16 15:20:36 -07003807 case HCI_EV_ENCRYPT_CHANGE:
3808 hci_encrypt_change_evt(hdev, skb);
3809 break;
3810
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003811 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3812 hci_change_link_key_complete_evt(hdev, skb);
3813 break;
3814
3815 case HCI_EV_REMOTE_FEATURES:
3816 hci_remote_features_evt(hdev, skb);
3817 break;
3818
3819 case HCI_EV_REMOTE_VERSION:
3820 hci_remote_version_evt(hdev, skb);
3821 break;
3822
3823 case HCI_EV_QOS_SETUP_COMPLETE:
3824 hci_qos_setup_complete_evt(hdev, skb);
3825 break;
3826
3827 case HCI_EV_CMD_COMPLETE:
3828 hci_cmd_complete_evt(hdev, skb);
3829 break;
3830
3831 case HCI_EV_CMD_STATUS:
3832 hci_cmd_status_evt(hdev, skb);
3833 break;
3834
3835 case HCI_EV_ROLE_CHANGE:
3836 hci_role_change_evt(hdev, skb);
3837 break;
3838
3839 case HCI_EV_NUM_COMP_PKTS:
3840 hci_num_comp_pkts_evt(hdev, skb);
3841 break;
3842
3843 case HCI_EV_MODE_CHANGE:
3844 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003845 break;
3846
3847 case HCI_EV_PIN_CODE_REQ:
3848 hci_pin_code_request_evt(hdev, skb);
3849 break;
3850
3851 case HCI_EV_LINK_KEY_REQ:
3852 hci_link_key_request_evt(hdev, skb);
3853 break;
3854
3855 case HCI_EV_LINK_KEY_NOTIFY:
3856 hci_link_key_notify_evt(hdev, skb);
3857 break;
3858
3859 case HCI_EV_CLOCK_OFFSET:
3860 hci_clock_offset_evt(hdev, skb);
3861 break;
3862
Marcel Holtmanna8746412008-07-14 20:13:46 +02003863 case HCI_EV_PKT_TYPE_CHANGE:
3864 hci_pkt_type_change_evt(hdev, skb);
3865 break;
3866
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003867 case HCI_EV_PSCAN_REP_MODE:
3868 hci_pscan_rep_mode_evt(hdev, skb);
3869 break;
3870
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003871 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3872 hci_inquiry_result_with_rssi_evt(hdev, skb);
3873 break;
3874
3875 case HCI_EV_REMOTE_EXT_FEATURES:
3876 hci_remote_ext_features_evt(hdev, skb);
3877 break;
3878
3879 case HCI_EV_SYNC_CONN_COMPLETE:
3880 hci_sync_conn_complete_evt(hdev, skb);
3881 break;
3882
3883 case HCI_EV_SYNC_CONN_CHANGED:
3884 hci_sync_conn_changed_evt(hdev, skb);
3885 break;
3886
Marcel Holtmann04837f62006-07-03 10:02:33 +02003887 case HCI_EV_SNIFF_SUBRATE:
3888 hci_sniff_subrate_evt(hdev, skb);
3889 break;
3890
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003891 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3892 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003893 break;
3894
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003895 case HCI_EV_KEY_REFRESH_COMPLETE:
3896 hci_key_refresh_complete_evt(hdev, skb);
3897 break;
3898
Marcel Holtmann04936842008-07-14 20:13:48 +02003899 case HCI_EV_IO_CAPA_REQUEST:
3900 hci_io_capa_request_evt(hdev, skb);
3901 break;
3902
Johan Hedberg03b555e2011-01-04 15:40:05 +02003903 case HCI_EV_IO_CAPA_REPLY:
3904 hci_io_capa_reply_evt(hdev, skb);
3905 break;
3906
Johan Hedberga5c29682011-02-19 12:05:57 -03003907 case HCI_EV_USER_CONFIRM_REQUEST:
3908 hci_user_confirm_request_evt(hdev, skb);
3909 break;
3910
Brian Gix1143d452011-11-23 08:28:34 -08003911 case HCI_EV_USER_PASSKEY_REQUEST:
3912 hci_user_passkey_request_evt(hdev, skb);
3913 break;
3914
Johan Hedberg92a25252012-09-06 18:39:26 +03003915 case HCI_EV_USER_PASSKEY_NOTIFY:
3916 hci_user_passkey_notify_evt(hdev, skb);
3917 break;
3918
3919 case HCI_EV_KEYPRESS_NOTIFY:
3920 hci_keypress_notify_evt(hdev, skb);
3921 break;
3922
Marcel Holtmann04936842008-07-14 20:13:48 +02003923 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3924 hci_simple_pair_complete_evt(hdev, skb);
3925 break;
3926
Marcel Holtmann41a96212008-07-14 20:13:48 +02003927 case HCI_EV_REMOTE_HOST_FEATURES:
3928 hci_remote_host_features_evt(hdev, skb);
3929 break;
3930
Ville Tervofcd89c02011-02-10 22:38:47 -03003931 case HCI_EV_LE_META:
3932 hci_le_meta_evt(hdev, skb);
3933 break;
3934
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003935 case HCI_EV_CHANNEL_SELECTED:
3936 hci_chan_selected_evt(hdev, skb);
3937 break;
3938
Szymon Janc2763eda2011-03-22 13:12:22 +01003939 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3940 hci_remote_oob_data_request_evt(hdev, skb);
3941 break;
3942
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003943 case HCI_EV_PHY_LINK_COMPLETE:
3944 hci_phy_link_complete_evt(hdev, skb);
3945 break;
3946
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003947 case HCI_EV_LOGICAL_LINK_COMPLETE:
3948 hci_loglink_complete_evt(hdev, skb);
3949 break;
3950
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003951 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3952 hci_disconn_loglink_complete_evt(hdev, skb);
3953 break;
3954
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003955 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3956 hci_disconn_phylink_complete_evt(hdev, skb);
3957 break;
3958
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003959 case HCI_EV_NUM_COMP_BLOCKS:
3960 hci_num_comp_blocks_evt(hdev, skb);
3961 break;
3962
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003963 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003964 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965 break;
3966 }
3967
3968 kfree_skb(skb);
3969 hdev->stat.evt_rx++;
3970}