blob: 5daf7ab26710b06336abf853bb5e8a1c51b5cc7f [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);
Andre Guedes3e13fa12013-03-27 20:04:56 -030051 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
52 wake_up_bit(&hdev->flags, HCI_INQUIRY);
Andre Guedes89352e72011-11-04 14:16:53 -030053
Johan Hedberg56e5cb82011-11-08 20:40:16 +020054 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020055 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020056 hci_dev_unlock(hdev);
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 */
Johan Hedberg2cc6fb02013-03-15 17:06:57 -0500197 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
Andre Guedes69775ff2012-02-23 16:50:05 +0200198
199 hdev->discovery.state = DISCOVERY_STOPPED;
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100200 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
201 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100202
203 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
204 hdev->adv_data_len = 0;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200205}
206
207static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
208{
209 __u8 status = *((__u8 *) skb->data);
210 void *sent;
211
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300212 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200213
214 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
215 if (!sent)
216 return;
217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 hci_dev_lock(hdev);
219
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200220 if (test_bit(HCI_MGMT, &hdev->dev_flags))
221 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200222 else if (!status)
223 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200224
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200225 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200226}
227
228static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
229{
230 struct hci_rp_read_local_name *rp = (void *) skb->data;
231
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300232 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200233
234 if (rp->status)
235 return;
236
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200237 if (test_bit(HCI_SETUP, &hdev->dev_flags))
238 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200239}
240
241static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
242{
243 __u8 status = *((__u8 *) skb->data);
244 void *sent;
245
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300246 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200247
248 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
249 if (!sent)
250 return;
251
252 if (!status) {
253 __u8 param = *((__u8 *) sent);
254
255 if (param == AUTH_ENABLED)
256 set_bit(HCI_AUTH, &hdev->flags);
257 else
258 clear_bit(HCI_AUTH, &hdev->flags);
259 }
260
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200261 if (test_bit(HCI_MGMT, &hdev->dev_flags))
262 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200263}
264
265static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
266{
267 __u8 status = *((__u8 *) skb->data);
268 void *sent;
269
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300270 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200271
272 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
273 if (!sent)
274 return;
275
276 if (!status) {
277 __u8 param = *((__u8 *) sent);
278
279 if (param)
280 set_bit(HCI_ENCRYPT, &hdev->flags);
281 else
282 clear_bit(HCI_ENCRYPT, &hdev->flags);
283 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200284}
285
286static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
287{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200288 __u8 param, status = *((__u8 *) skb->data);
289 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200290 void *sent;
291
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300292 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200293
294 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
295 if (!sent)
296 return;
297
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200298 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200299
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200300 hci_dev_lock(hdev);
301
Mikel Astizfa1bd912012-08-09 09:52:29 +0200302 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200303 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200304 hdev->discov_timeout = 0;
305 goto done;
306 }
307
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200308 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
309 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200310
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200311 if (param & SCAN_INQUIRY) {
312 set_bit(HCI_ISCAN, &hdev->flags);
313 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200314 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200315 if (hdev->discov_timeout > 0) {
316 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
317 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300318 to);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200319 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200320 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200321 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200322
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 if (param & SCAN_PAGE) {
324 set_bit(HCI_PSCAN, &hdev->flags);
325 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200328 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200329
330done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200331 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200332}
333
334static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
335{
336 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
337
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300338 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200339
340 if (rp->status)
341 return;
342
343 memcpy(hdev->dev_class, rp->dev_class, 3);
344
345 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300346 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200347}
348
349static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
350{
351 __u8 status = *((__u8 *) skb->data);
352 void *sent;
353
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300354 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200355
356 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
357 if (!sent)
358 return;
359
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100360 hci_dev_lock(hdev);
361
362 if (status == 0)
363 memcpy(hdev->dev_class, sent, 3);
364
365 if (test_bit(HCI_MGMT, &hdev->dev_flags))
366 mgmt_set_class_of_dev_complete(hdev, sent, status);
367
368 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200369}
370
371static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
372{
373 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300376 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200377
378 if (rp->status)
379 return;
380
381 setting = __le16_to_cpu(rp->voice_setting);
382
Marcel Holtmannf383f272008-07-14 20:13:47 +0200383 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384 return;
385
386 hdev->voice_setting = setting;
387
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300388 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200390 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200391 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392}
393
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300394static void hci_cc_write_voice_setting(struct hci_dev *hdev,
395 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200396{
397 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200398 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 void *sent;
400
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300401 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Marcel Holtmannf383f272008-07-14 20:13:47 +0200403 if (status)
404 return;
405
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200406 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
407 if (!sent)
408 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Marcel Holtmannf383f272008-07-14 20:13:47 +0200412 if (hdev->voice_setting == setting)
413 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Marcel Holtmannf383f272008-07-14 20:13:47 +0200415 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300417 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200418
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200419 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200420 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421}
422
Marcel Holtmann333140b2008-07-14 20:13:48 +0200423static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
424{
425 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300426 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200427
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300428 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200429
Marcel Holtmann333140b2008-07-14 20:13:48 +0200430 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
431 if (!sent)
432 return;
433
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300434 if (!status) {
435 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300436 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300437 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300438 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300439 }
440
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200441 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300442 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200443 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300444 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200445 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
446 else
447 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
448 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200449}
450
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200451static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
452{
453 struct hci_rp_read_local_version *rp = (void *) skb->data;
454
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300455 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200456
457 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200458 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200459
460 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200461 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200462 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200463 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200464 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200465
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300466 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300467 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200468}
469
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300470static void hci_cc_read_local_commands(struct hci_dev *hdev,
471 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200472{
473 struct hci_rp_read_local_commands *rp = (void *) skb->data;
474
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300475 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200476
Johan Hedberg2177bab2013-03-05 20:37:43 +0200477 if (!rp->status)
478 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200479}
480
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300481static void hci_cc_read_local_features(struct hci_dev *hdev,
482 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200483{
484 struct hci_rp_read_local_features *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
488 if (rp->status)
489 return;
490
491 memcpy(hdev->features, rp->features, 8);
492
493 /* Adjust default settings according to features
494 * supported by device. */
495
Johan Hedbergcad718e2013-04-17 15:00:51 +0300496 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200497 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
498
Johan Hedbergcad718e2013-04-17 15:00:51 +0300499 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200500 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
501
Johan Hedbergcad718e2013-04-17 15:00:51 +0300502 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200503 hdev->pkt_type |= (HCI_HV2);
504 hdev->esco_type |= (ESCO_HV2);
505 }
506
Johan Hedbergcad718e2013-04-17 15:00:51 +0300507 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200508 hdev->pkt_type |= (HCI_HV3);
509 hdev->esco_type |= (ESCO_HV3);
510 }
511
Andre Guedes45db810f2012-07-24 15:03:49 -0300512 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200513 hdev->esco_type |= (ESCO_EV3);
514
Johan Hedbergcad718e2013-04-17 15:00:51 +0300515 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200516 hdev->esco_type |= (ESCO_EV4);
517
Johan Hedbergcad718e2013-04-17 15:00:51 +0300518 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200519 hdev->esco_type |= (ESCO_EV5);
520
Johan Hedbergcad718e2013-04-17 15:00:51 +0300521 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100522 hdev->esco_type |= (ESCO_2EV3);
523
Johan Hedbergcad718e2013-04-17 15:00:51 +0300524 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100525 hdev->esco_type |= (ESCO_3EV3);
526
Johan Hedbergcad718e2013-04-17 15:00:51 +0300527 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100528 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
529
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200530 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
Johan Hedbergcad718e2013-04-17 15:00:51 +0300531 hdev->features[0][0], hdev->features[0][1],
532 hdev->features[0][2], hdev->features[0][3],
533 hdev->features[0][4], hdev->features[0][5],
534 hdev->features[0][6], hdev->features[0][7]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200535}
536
Andre Guedes971e3a42011-06-30 19:20:52 -0300537static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300538 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300539{
540 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
541
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300542 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300543
544 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200545 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300546
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300547 hdev->max_page = rp->max_page;
548
Johan Hedbergcad718e2013-04-17 15:00:51 +0300549 if (rp->page < HCI_MAX_PAGES)
550 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300551}
552
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200553static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300554 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200555{
556 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
557
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300558 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200559
Johan Hedberg42c6b122013-03-05 20:37:49 +0200560 if (!rp->status)
561 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200562}
563
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200564static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
565{
566 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
567
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300568 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200569
570 if (rp->status)
571 return;
572
573 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
574 hdev->sco_mtu = rp->sco_mtu;
575 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
576 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
577
578 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
579 hdev->sco_mtu = 64;
580 hdev->sco_pkts = 8;
581 }
582
583 hdev->acl_cnt = hdev->acl_pkts;
584 hdev->sco_cnt = hdev->sco_pkts;
585
Gustavo Padovan807deac2012-05-17 00:36:24 -0300586 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
587 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200588}
589
590static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
591{
592 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
593
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300594 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200595
596 if (!rp->status)
597 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200598}
599
Johan Hedbergf332ec62013-03-15 17:07:11 -0500600static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
601 struct sk_buff *skb)
602{
603 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
604
605 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
606
607 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
608 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
609 hdev->page_scan_window = __le16_to_cpu(rp->window);
610 }
611}
612
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500613static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
614 struct sk_buff *skb)
615{
616 u8 status = *((u8 *) skb->data);
617 struct hci_cp_write_page_scan_activity *sent;
618
619 BT_DBG("%s status 0x%2.2x", hdev->name, status);
620
621 if (status)
622 return;
623
624 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
625 if (!sent)
626 return;
627
628 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
629 hdev->page_scan_window = __le16_to_cpu(sent->window);
630}
631
Johan Hedbergf332ec62013-03-15 17:07:11 -0500632static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
633 struct sk_buff *skb)
634{
635 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
636
637 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
638
639 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
640 hdev->page_scan_type = rp->type;
641}
642
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500643static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
644 struct sk_buff *skb)
645{
646 u8 status = *((u8 *) skb->data);
647 u8 *type;
648
649 BT_DBG("%s status 0x%2.2x", hdev->name, status);
650
651 if (status)
652 return;
653
654 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
655 if (type)
656 hdev->page_scan_type = *type;
657}
658
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200659static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300660 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200661{
662 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
663
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300664 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200665
666 if (rp->status)
667 return;
668
669 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
670 hdev->block_len = __le16_to_cpu(rp->block_len);
671 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
672
673 hdev->block_cnt = hdev->num_blocks;
674
675 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300676 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200677}
678
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300679static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300680 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300681{
682 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
683
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300684 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300685
686 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300687 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300688
689 hdev->amp_status = rp->amp_status;
690 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
691 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
692 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
693 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
694 hdev->amp_type = rp->amp_type;
695 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
696 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
697 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
698 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
699
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300700a2mp_rsp:
701 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300702}
703
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300704static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
705 struct sk_buff *skb)
706{
707 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
708 struct amp_assoc *assoc = &hdev->loc_assoc;
709 size_t rem_len, frag_len;
710
711 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
712
713 if (rp->status)
714 goto a2mp_rsp;
715
716 frag_len = skb->len - sizeof(*rp);
717 rem_len = __le16_to_cpu(rp->rem_len);
718
719 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300720 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300721
722 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
723 assoc->offset += frag_len;
724
725 /* Read other fragments */
726 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
727
728 return;
729 }
730
731 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
732 assoc->len = assoc->offset + rem_len;
733 assoc->offset = 0;
734
735a2mp_rsp:
736 /* Send A2MP Rsp when all fragments are received */
737 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300738 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300739}
740
Johan Hedbergd5859e22011-01-25 01:19:58 +0200741static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300742 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200743{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700744 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200745
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300746 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200747
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700748 if (!rp->status)
749 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200750}
751
Johan Hedberg980e1a52011-01-22 06:10:07 +0200752static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
753{
754 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
755 struct hci_cp_pin_code_reply *cp;
756 struct hci_conn *conn;
757
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300758 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200759
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200760 hci_dev_lock(hdev);
761
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200762 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200763 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200764
Mikel Astizfa1bd912012-08-09 09:52:29 +0200765 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200766 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200767
768 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
769 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200770 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200771
772 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
773 if (conn)
774 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200775
776unlock:
777 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200778}
779
780static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
781{
782 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
783
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300784 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200785
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200786 hci_dev_lock(hdev);
787
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200788 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200789 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300790 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200791
792 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200793}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200794
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300795static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
796 struct sk_buff *skb)
797{
798 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
799
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300800 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300801
802 if (rp->status)
803 return;
804
805 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
806 hdev->le_pkts = rp->le_max_pkt;
807
808 hdev->le_cnt = hdev->le_pkts;
809
810 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300811}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200812
Johan Hedberg60e77322013-01-22 14:01:59 +0200813static void hci_cc_le_read_local_features(struct hci_dev *hdev,
814 struct sk_buff *skb)
815{
816 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
817
818 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
819
820 if (!rp->status)
821 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200822}
823
Johan Hedberg8fa19092012-10-19 20:57:49 +0300824static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
825 struct sk_buff *skb)
826{
827 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
828
829 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
830
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500831 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300832 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300833}
834
Johan Hedberga5c29682011-02-19 12:05:57 -0300835static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
836{
837 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
838
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300839 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300840
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200841 hci_dev_lock(hdev);
842
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200843 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300844 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
845 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200846
847 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300848}
849
850static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300851 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300852{
853 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
854
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300855 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300856
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200857 hci_dev_lock(hdev);
858
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200859 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200860 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300861 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200862
863 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300864}
865
Brian Gix1143d452011-11-23 08:28:34 -0800866static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
867{
868 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
869
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300870 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800871
872 hci_dev_lock(hdev);
873
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200874 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200875 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300876 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800877
878 hci_dev_unlock(hdev);
879}
880
881static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300882 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800883{
884 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
885
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300886 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800887
888 hci_dev_lock(hdev);
889
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200890 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800891 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300892 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800893
894 hci_dev_unlock(hdev);
895}
896
Szymon Jancc35938b2011-03-22 13:12:21 +0100897static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300898 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100899{
900 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
901
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300902 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100903
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200904 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200905 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100906 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200907 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100908}
909
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100910static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
911{
912 __u8 *sent, status = *((__u8 *) skb->data);
913
914 BT_DBG("%s status 0x%2.2x", hdev->name, status);
915
916 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
917 if (!sent)
918 return;
919
920 hci_dev_lock(hdev);
921
922 if (!status) {
923 if (*sent)
924 set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
925 else
926 clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
927 }
928
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500929 if (!test_bit(HCI_INIT, &hdev->flags)) {
930 struct hci_request req;
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100931
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500932 hci_req_init(&req, hdev);
933 hci_update_ad(&req);
934 hci_req_run(&req, NULL);
935 }
936
937 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100938}
939
Andre Guedes07f7fa52011-12-02 21:13:31 +0900940static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
941{
942 __u8 status = *((__u8 *) skb->data);
943
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300944 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300945
Andre Guedes3fd24152012-02-03 17:48:01 -0300946 if (status) {
947 hci_dev_lock(hdev);
948 mgmt_start_discovery_failed(hdev, status);
949 hci_dev_unlock(hdev);
950 return;
951 }
Andre Guedes07f7fa52011-12-02 21:13:31 +0900952}
953
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300954static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300955 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300956{
957 struct hci_cp_le_set_scan_enable *cp;
958 __u8 status = *((__u8 *) skb->data);
959
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300960 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300961
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300962 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
963 if (!cp)
964 return;
965
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200966 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -0300967 case LE_SCAN_ENABLE:
Andre Guedes3fd24152012-02-03 17:48:01 -0300968 if (status) {
969 hci_dev_lock(hdev);
970 mgmt_start_discovery_failed(hdev, status);
971 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300972 return;
Andre Guedes3fd24152012-02-03 17:48:01 -0300973 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300974
Andre Guedesd23264a2011-11-25 20:53:38 -0300975 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
976
Andre Guedesa8f13c82011-09-09 18:56:24 -0300977 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -0300978 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -0300979 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200980 break;
981
Andre Guedes76a388b2013-04-04 20:21:02 -0300982 case LE_SCAN_DISABLE:
Andre Guedesc9ecc482012-03-15 16:52:08 -0300983 if (status) {
984 hci_dev_lock(hdev);
985 mgmt_stop_discovery_failed(hdev, status);
986 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300987 return;
Andre Guedesc9ecc482012-03-15 16:52:08 -0300988 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300989
Andre Guedesd23264a2011-11-25 20:53:38 -0300990 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
991
Andre Guedesbc3dd332012-03-06 19:37:06 -0300992 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
993 hdev->discovery.state == DISCOVERY_FINDING) {
Andre Guedes5e0452c2012-02-17 20:39:38 -0300994 mgmt_interleaved_discovery(hdev);
995 } else {
996 hci_dev_lock(hdev);
997 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
998 hci_dev_unlock(hdev);
999 }
1000
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001001 break;
1002
1003 default:
1004 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1005 break;
Andre Guedes35815082011-05-26 16:23:53 -03001006 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001007}
1008
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001009static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1010 struct sk_buff *skb)
1011{
1012 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1013
1014 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1015
1016 if (!rp->status)
1017 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001018}
1019
Johan Hedberg9b008c02013-01-22 14:02:01 +02001020static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1021 struct sk_buff *skb)
1022{
1023 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1024
1025 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1026
1027 if (!rp->status)
1028 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001029}
1030
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001031static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1032 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001033{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001034 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001035 __u8 status = *((__u8 *) skb->data);
1036
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001037 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001038
Johan Hedberg06199cf2012-02-22 16:37:11 +02001039 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001040 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001041 return;
1042
Johan Hedberg8f984df2012-02-28 01:07:22 +02001043 if (!status) {
1044 if (sent->le)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001045 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001046 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001047 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001048
1049 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001050 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001051 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001052 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001053 }
1054
1055 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001056 !test_bit(HCI_INIT, &hdev->flags))
Johan Hedberg8f984df2012-02-28 01:07:22 +02001057 mgmt_le_enable_complete(hdev, sent->le, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001058}
1059
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001060static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1061 struct sk_buff *skb)
1062{
1063 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1064
1065 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1066 hdev->name, rp->status, rp->phy_handle);
1067
1068 if (rp->status)
1069 return;
1070
1071 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1072}
1073
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001074static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001075{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001076 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001077
1078 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001079 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001080 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001081 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001082 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001083 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001084 return;
1085 }
1086
Andre Guedes89352e72011-11-04 14:16:53 -03001087 set_bit(HCI_INQUIRY, &hdev->flags);
1088
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001089 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001090 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001091 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001092}
1093
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001094static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001096 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001099 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001100
1101 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102 if (!cp)
1103 return;
1104
1105 hci_dev_lock(hdev);
1106
1107 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1108
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001109 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110
1111 if (status) {
1112 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001113 if (status != 0x0c || conn->attempt > 2) {
1114 conn->state = BT_CLOSED;
1115 hci_proto_connect_cfm(conn, status);
1116 hci_conn_del(conn);
1117 } else
1118 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119 }
1120 } else {
1121 if (!conn) {
1122 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1123 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001124 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125 conn->link_mode |= HCI_LM_MASTER;
1126 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001127 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 }
1129 }
1130
1131 hci_dev_unlock(hdev);
1132}
1133
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001134static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001136 struct hci_cp_add_sco *cp;
1137 struct hci_conn *acl, *sco;
1138 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001140 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001141
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001142 if (!status)
1143 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001145 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1146 if (!cp)
1147 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001149 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001151 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001152
1153 hci_dev_lock(hdev);
1154
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001155 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001156 if (acl) {
1157 sco = acl->link;
1158 if (sco) {
1159 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001160
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001161 hci_proto_connect_cfm(sco, status);
1162 hci_conn_del(sco);
1163 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001164 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001165
1166 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167}
1168
Marcel Holtmannf8558552008-07-14 20:13:49 +02001169static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1170{
1171 struct hci_cp_auth_requested *cp;
1172 struct hci_conn *conn;
1173
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001174 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001175
1176 if (!status)
1177 return;
1178
1179 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1180 if (!cp)
1181 return;
1182
1183 hci_dev_lock(hdev);
1184
1185 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1186 if (conn) {
1187 if (conn->state == BT_CONFIG) {
1188 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001189 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001190 }
1191 }
1192
1193 hci_dev_unlock(hdev);
1194}
1195
1196static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1197{
1198 struct hci_cp_set_conn_encrypt *cp;
1199 struct hci_conn *conn;
1200
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001201 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001202
1203 if (!status)
1204 return;
1205
1206 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1207 if (!cp)
1208 return;
1209
1210 hci_dev_lock(hdev);
1211
1212 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1213 if (conn) {
1214 if (conn->state == BT_CONFIG) {
1215 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001216 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001217 }
1218 }
1219
1220 hci_dev_unlock(hdev);
1221}
1222
Johan Hedberg127178d2010-11-18 22:22:29 +02001223static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001224 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001225{
Johan Hedberg392599b2010-11-18 22:22:28 +02001226 if (conn->state != BT_CONFIG || !conn->out)
1227 return 0;
1228
Johan Hedberg765c2a92011-01-19 12:06:52 +05301229 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001230 return 0;
1231
1232 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001233 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001234 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1235 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001236 return 0;
1237
Johan Hedberg392599b2010-11-18 22:22:28 +02001238 return 1;
1239}
1240
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001241static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001242 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001243{
1244 struct hci_cp_remote_name_req cp;
1245
1246 memset(&cp, 0, sizeof(cp));
1247
1248 bacpy(&cp.bdaddr, &e->data.bdaddr);
1249 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1250 cp.pscan_mode = e->data.pscan_mode;
1251 cp.clock_offset = e->data.clock_offset;
1252
1253 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1254}
1255
Johan Hedbergb644ba32012-01-17 21:48:47 +02001256static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001257{
1258 struct discovery_state *discov = &hdev->discovery;
1259 struct inquiry_entry *e;
1260
Johan Hedbergb644ba32012-01-17 21:48:47 +02001261 if (list_empty(&discov->resolve))
1262 return false;
1263
1264 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001265 if (!e)
1266 return false;
1267
Johan Hedbergb644ba32012-01-17 21:48:47 +02001268 if (hci_resolve_name(hdev, e) == 0) {
1269 e->name_state = NAME_PENDING;
1270 return true;
1271 }
1272
1273 return false;
1274}
1275
1276static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001277 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001278{
1279 struct discovery_state *discov = &hdev->discovery;
1280 struct inquiry_entry *e;
1281
1282 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001283 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1284 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001285
1286 if (discov->state == DISCOVERY_STOPPED)
1287 return;
1288
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001289 if (discov->state == DISCOVERY_STOPPING)
1290 goto discov_complete;
1291
1292 if (discov->state != DISCOVERY_RESOLVING)
1293 return;
1294
1295 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001296 /* If the device was not found in a list of found devices names of which
1297 * are pending. there is no need to continue resolving a next name as it
1298 * will be done upon receiving another Remote Name Request Complete
1299 * Event */
1300 if (!e)
1301 return;
1302
1303 list_del(&e->list);
1304 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001305 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001306 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1307 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001308 } else {
1309 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001310 }
1311
Johan Hedbergb644ba32012-01-17 21:48:47 +02001312 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001313 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001314
1315discov_complete:
1316 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1317}
1318
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001319static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1320{
Johan Hedberg127178d2010-11-18 22:22:29 +02001321 struct hci_cp_remote_name_req *cp;
1322 struct hci_conn *conn;
1323
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001324 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001325
1326 /* If successful wait for the name req complete event before
1327 * checking for the need to do authentication */
1328 if (!status)
1329 return;
1330
1331 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1332 if (!cp)
1333 return;
1334
1335 hci_dev_lock(hdev);
1336
1337 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001338
1339 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1340 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1341
Johan Hedberg79c6c702011-04-28 11:28:55 -07001342 if (!conn)
1343 goto unlock;
1344
1345 if (!hci_outgoing_auth_needed(hdev, conn))
1346 goto unlock;
1347
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001348 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001349 struct hci_cp_auth_requested cp;
1350 cp.handle = __cpu_to_le16(conn->handle);
1351 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1352 }
1353
Johan Hedberg79c6c702011-04-28 11:28:55 -07001354unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001355 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001356}
1357
Marcel Holtmann769be972008-07-14 20:13:49 +02001358static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1359{
1360 struct hci_cp_read_remote_features *cp;
1361 struct hci_conn *conn;
1362
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001363 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001364
1365 if (!status)
1366 return;
1367
1368 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1369 if (!cp)
1370 return;
1371
1372 hci_dev_lock(hdev);
1373
1374 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1375 if (conn) {
1376 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001377 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001378 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001379 }
1380 }
1381
1382 hci_dev_unlock(hdev);
1383}
1384
1385static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1386{
1387 struct hci_cp_read_remote_ext_features *cp;
1388 struct hci_conn *conn;
1389
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001390 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001391
1392 if (!status)
1393 return;
1394
1395 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1396 if (!cp)
1397 return;
1398
1399 hci_dev_lock(hdev);
1400
1401 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1402 if (conn) {
1403 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001404 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001405 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001406 }
1407 }
1408
1409 hci_dev_unlock(hdev);
1410}
1411
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001412static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1413{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001414 struct hci_cp_setup_sync_conn *cp;
1415 struct hci_conn *acl, *sco;
1416 __u16 handle;
1417
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001418 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001419
1420 if (!status)
1421 return;
1422
1423 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1424 if (!cp)
1425 return;
1426
1427 handle = __le16_to_cpu(cp->handle);
1428
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001429 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001430
1431 hci_dev_lock(hdev);
1432
1433 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001434 if (acl) {
1435 sco = acl->link;
1436 if (sco) {
1437 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001438
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001439 hci_proto_connect_cfm(sco, status);
1440 hci_conn_del(sco);
1441 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001442 }
1443
1444 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001445}
1446
1447static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1448{
1449 struct hci_cp_sniff_mode *cp;
1450 struct hci_conn *conn;
1451
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001452 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001453
1454 if (!status)
1455 return;
1456
1457 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1458 if (!cp)
1459 return;
1460
1461 hci_dev_lock(hdev);
1462
1463 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001464 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001465 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001466
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001467 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001468 hci_sco_setup(conn, status);
1469 }
1470
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001471 hci_dev_unlock(hdev);
1472}
1473
1474static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1475{
1476 struct hci_cp_exit_sniff_mode *cp;
1477 struct hci_conn *conn;
1478
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001479 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001480
1481 if (!status)
1482 return;
1483
1484 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1485 if (!cp)
1486 return;
1487
1488 hci_dev_lock(hdev);
1489
1490 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001491 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001492 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001493
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001494 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001495 hci_sco_setup(conn, status);
1496 }
1497
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001498 hci_dev_unlock(hdev);
1499}
1500
Johan Hedberg88c3df12012-02-09 14:27:38 +02001501static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1502{
1503 struct hci_cp_disconnect *cp;
1504 struct hci_conn *conn;
1505
1506 if (!status)
1507 return;
1508
1509 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1510 if (!cp)
1511 return;
1512
1513 hci_dev_lock(hdev);
1514
1515 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1516 if (conn)
1517 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001518 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001519
1520 hci_dev_unlock(hdev);
1521}
1522
Ville Tervofcd89c02011-02-10 22:38:47 -03001523static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1524{
Ville Tervofcd89c02011-02-10 22:38:47 -03001525 struct hci_conn *conn;
1526
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001527 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Ville Tervofcd89c02011-02-10 22:38:47 -03001528
Ville Tervofcd89c02011-02-10 22:38:47 -03001529 if (status) {
Andre Guedesf00a06a2012-07-27 15:10:13 -03001530 hci_dev_lock(hdev);
Ville Tervofcd89c02011-02-10 22:38:47 -03001531
Andre Guedes0c95ab72012-07-27 15:10:14 -03001532 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001533 if (!conn) {
1534 hci_dev_unlock(hdev);
1535 return;
1536 }
1537
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001538 BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001539
1540 conn->state = BT_CLOSED;
Andre Guedes0c95ab72012-07-27 15:10:14 -03001541 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Andre Guedesf00a06a2012-07-27 15:10:13 -03001542 conn->dst_type, status);
1543 hci_proto_connect_cfm(conn, status);
1544 hci_conn_del(conn);
1545
1546 hci_dev_unlock(hdev);
1547 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001548}
1549
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001550static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1551{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001552 struct hci_cp_create_phy_link *cp;
1553
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001554 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001555
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001556 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1557 if (!cp)
1558 return;
1559
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001560 hci_dev_lock(hdev);
1561
1562 if (status) {
1563 struct hci_conn *hcon;
1564
1565 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1566 if (hcon)
1567 hci_conn_del(hcon);
1568 } else {
1569 amp_write_remote_assoc(hdev, cp->phy_handle);
1570 }
1571
1572 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001573}
1574
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001575static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1576{
1577 struct hci_cp_accept_phy_link *cp;
1578
1579 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1580
1581 if (status)
1582 return;
1583
1584 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1585 if (!cp)
1586 return;
1587
1588 amp_write_remote_assoc(hdev, cp->phy_handle);
1589}
1590
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001591static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001592{
1593 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001594 struct discovery_state *discov = &hdev->discovery;
1595 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001596
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001597 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001598
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001599 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001600
1601 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1602 return;
1603
Andre Guedes3e13fa12013-03-27 20:04:56 -03001604 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1605 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1606
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001607 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001608 return;
1609
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001610 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001611
Andre Guedes343f9352012-02-17 20:39:37 -03001612 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001613 goto unlock;
1614
1615 if (list_empty(&discov->resolve)) {
1616 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1617 goto unlock;
1618 }
1619
1620 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1621 if (e && hci_resolve_name(hdev, e) == 0) {
1622 e->name_state = NAME_PENDING;
1623 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1624 } else {
1625 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1626 }
1627
1628unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001629 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001630}
1631
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001632static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001634 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001635 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 int num_rsp = *((__u8 *) skb->data);
1637
1638 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1639
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001640 if (!num_rsp)
1641 return;
1642
Andre Guedes1519cc12012-03-21 00:03:38 -03001643 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1644 return;
1645
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001647
Johan Hedberge17acd42011-03-30 23:57:16 +03001648 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001649 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001650
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 bacpy(&data.bdaddr, &info->bdaddr);
1652 data.pscan_rep_mode = info->pscan_rep_mode;
1653 data.pscan_period_mode = info->pscan_period_mode;
1654 data.pscan_mode = info->pscan_mode;
1655 memcpy(data.dev_class, info->dev_class, 3);
1656 data.clock_offset = info->clock_offset;
1657 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001658 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001659
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001660 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001661 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001662 info->dev_class, 0, !name_known, ssp, NULL,
1663 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001665
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 hci_dev_unlock(hdev);
1667}
1668
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001669static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001671 struct hci_ev_conn_complete *ev = (void *) skb->data;
1672 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001674 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001675
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001677
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001678 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001679 if (!conn) {
1680 if (ev->link_type != SCO_LINK)
1681 goto unlock;
1682
1683 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1684 if (!conn)
1685 goto unlock;
1686
1687 conn->type = SCO_LINK;
1688 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001689
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001690 if (!ev->status) {
1691 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001692
1693 if (conn->type == ACL_LINK) {
1694 conn->state = BT_CONFIG;
1695 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001696
1697 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1698 !hci_find_link_key(hdev, &ev->bdaddr))
1699 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1700 else
1701 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001702 } else
1703 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001704
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001705 hci_conn_add_sysfs(conn);
1706
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001707 if (test_bit(HCI_AUTH, &hdev->flags))
1708 conn->link_mode |= HCI_LM_AUTH;
1709
1710 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1711 conn->link_mode |= HCI_LM_ENCRYPT;
1712
1713 /* Get remote features */
1714 if (conn->type == ACL_LINK) {
1715 struct hci_cp_read_remote_features cp;
1716 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001717 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001718 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001719 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001720
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001721 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001722 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001723 struct hci_cp_change_conn_ptype cp;
1724 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001725 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001726 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1727 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001728 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001729 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001730 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001731 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001732 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001733 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001734 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001735
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001736 if (conn->type == ACL_LINK)
1737 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001738
Marcel Holtmann769be972008-07-14 20:13:49 +02001739 if (ev->status) {
1740 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001741 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001742 } else if (ev->link_type != ACL_LINK)
1743 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001744
1745unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001747
1748 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749}
1750
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001751static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001753 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001755 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001757 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001758 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001760 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1761 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762
Szymon Janc138d22e2011-02-17 16:44:23 +01001763 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001764 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001766 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768
1769 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001770
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001771 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1772 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001773 memcpy(ie->data.dev_class, ev->dev_class, 3);
1774
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001775 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1776 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001778 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1779 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001780 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781 hci_dev_unlock(hdev);
1782 return;
1783 }
1784 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001785
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001787
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 hci_dev_unlock(hdev);
1789
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001790 if (ev->link_type == ACL_LINK ||
1791 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001792 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001793 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001795 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001797 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1798 cp.role = 0x00; /* Become master */
1799 else
1800 cp.role = 0x01; /* Remain slave */
1801
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001802 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1803 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001804 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001805 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001806 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001807
1808 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001809 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001810
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001811 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1812 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1813 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001814 cp.content_format = cpu_to_le16(hdev->voice_setting);
1815 cp.retrans_effort = 0xff;
1816
1817 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001818 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001819 } else {
1820 conn->state = BT_CONNECT2;
1821 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001822 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 } else {
1824 /* Connection rejected */
1825 struct hci_cp_reject_conn_req cp;
1826
1827 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001828 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001829 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 }
1831}
1832
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001833static u8 hci_to_mgmt_reason(u8 err)
1834{
1835 switch (err) {
1836 case HCI_ERROR_CONNECTION_TIMEOUT:
1837 return MGMT_DEV_DISCONN_TIMEOUT;
1838 case HCI_ERROR_REMOTE_USER_TERM:
1839 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1840 case HCI_ERROR_REMOTE_POWER_OFF:
1841 return MGMT_DEV_DISCONN_REMOTE;
1842 case HCI_ERROR_LOCAL_HOST_TERM:
1843 return MGMT_DEV_DISCONN_LOCAL_HOST;
1844 default:
1845 return MGMT_DEV_DISCONN_UNKNOWN;
1846 }
1847}
1848
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001849static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001851 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001852 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001854 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 hci_dev_lock(hdev);
1857
Marcel Holtmann04837f62006-07-03 10:02:33 +02001858 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001859 if (!conn)
1860 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001861
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001862 if (ev->status == 0)
1863 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864
Johan Hedbergb644ba32012-01-17 21:48:47 +02001865 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001866 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001867 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001868 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001869 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001870 } else {
1871 u8 reason = hci_to_mgmt_reason(ev->reason);
1872
Johan Hedbergafc747a2012-01-15 18:11:07 +02001873 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001874 conn->dst_type, reason);
1875 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001876 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001877
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001878 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301879 if (conn->type == ACL_LINK && conn->flush_key)
1880 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001881 hci_proto_disconn_cfm(conn, ev->reason);
1882 hci_conn_del(conn);
1883 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001884
1885unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 hci_dev_unlock(hdev);
1887}
1888
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001889static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001890{
1891 struct hci_ev_auth_complete *ev = (void *) skb->data;
1892 struct hci_conn *conn;
1893
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001894 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001895
1896 hci_dev_lock(hdev);
1897
1898 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001899 if (!conn)
1900 goto unlock;
1901
1902 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001903 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001904 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001905 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001906 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001907 conn->link_mode |= HCI_LM_AUTH;
1908 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001909 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001910 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001911 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001912 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001913 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001914
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001915 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1916 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001917
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001918 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001919 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001920 struct hci_cp_set_conn_encrypt cp;
1921 cp.handle = ev->handle;
1922 cp.encrypt = 0x01;
1923 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001924 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001925 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001926 conn->state = BT_CONNECTED;
1927 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001928 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001929 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001930 } else {
1931 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001932
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001933 hci_conn_hold(conn);
1934 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001935 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001936 }
1937
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001938 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001939 if (!ev->status) {
1940 struct hci_cp_set_conn_encrypt cp;
1941 cp.handle = ev->handle;
1942 cp.encrypt = 0x01;
1943 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001944 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001945 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001946 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001947 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001948 }
1949 }
1950
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001951unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001952 hci_dev_unlock(hdev);
1953}
1954
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001955static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001956{
Johan Hedberg127178d2010-11-18 22:22:29 +02001957 struct hci_ev_remote_name *ev = (void *) skb->data;
1958 struct hci_conn *conn;
1959
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001960 BT_DBG("%s", hdev->name);
1961
1962 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001963
1964 hci_dev_lock(hdev);
1965
1966 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001967
1968 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1969 goto check_auth;
1970
1971 if (ev->status == 0)
1972 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001973 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001974 else
1975 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1976
1977check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001978 if (!conn)
1979 goto unlock;
1980
1981 if (!hci_outgoing_auth_needed(hdev, conn))
1982 goto unlock;
1983
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001984 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001985 struct hci_cp_auth_requested cp;
1986 cp.handle = __cpu_to_le16(conn->handle);
1987 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1988 }
1989
Johan Hedberg79c6c702011-04-28 11:28:55 -07001990unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001991 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001992}
1993
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001994static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001995{
1996 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1997 struct hci_conn *conn;
1998
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001999 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002000
2001 hci_dev_lock(hdev);
2002
2003 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2004 if (conn) {
2005 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002006 if (ev->encrypt) {
2007 /* Encryption implies authentication */
2008 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002009 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002010 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002011 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002012 conn->link_mode &= ~HCI_LM_ENCRYPT;
2013 }
2014
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002015 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002016
Gustavo Padovana7d77232012-05-13 03:20:07 -03002017 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03002018 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02002019 hci_conn_drop(conn);
Gustavo Padovana7d77232012-05-13 03:20:07 -03002020 goto unlock;
2021 }
2022
Marcel Holtmannf8558552008-07-14 20:13:49 +02002023 if (conn->state == BT_CONFIG) {
2024 if (!ev->status)
2025 conn->state = BT_CONNECTED;
2026
2027 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002028 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02002029 } else
2030 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002031 }
2032
Gustavo Padovana7d77232012-05-13 03:20:07 -03002033unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002034 hci_dev_unlock(hdev);
2035}
2036
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002037static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2038 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002039{
2040 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2041 struct hci_conn *conn;
2042
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002043 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002044
2045 hci_dev_lock(hdev);
2046
2047 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2048 if (conn) {
2049 if (!ev->status)
2050 conn->link_mode |= HCI_LM_SECURE;
2051
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002052 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002053
2054 hci_key_change_cfm(conn, ev->status);
2055 }
2056
2057 hci_dev_unlock(hdev);
2058}
2059
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002060static void hci_remote_features_evt(struct hci_dev *hdev,
2061 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002062{
2063 struct hci_ev_remote_features *ev = (void *) skb->data;
2064 struct hci_conn *conn;
2065
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002066 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002067
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002068 hci_dev_lock(hdev);
2069
2070 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002071 if (!conn)
2072 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002073
Johan Hedbergccd556f2010-11-10 17:11:51 +02002074 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002075 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002076
2077 if (conn->state != BT_CONFIG)
2078 goto unlock;
2079
2080 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2081 struct hci_cp_read_remote_ext_features cp;
2082 cp.handle = ev->handle;
2083 cp.page = 0x01;
2084 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002085 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002086 goto unlock;
2087 }
2088
Johan Hedberg671267b2012-05-12 16:11:50 -03002089 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002090 struct hci_cp_remote_name_req cp;
2091 memset(&cp, 0, sizeof(cp));
2092 bacpy(&cp.bdaddr, &conn->dst);
2093 cp.pscan_rep_mode = 0x02;
2094 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002095 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2096 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002097 conn->dst_type, 0, NULL, 0,
2098 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002099
Johan Hedberg127178d2010-11-18 22:22:29 +02002100 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002101 conn->state = BT_CONNECTED;
2102 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002103 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002104 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002105
Johan Hedbergccd556f2010-11-10 17:11:51 +02002106unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002107 hci_dev_unlock(hdev);
2108}
2109
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002110static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002111{
2112 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002113 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002114 __u16 opcode;
2115
2116 skb_pull(skb, sizeof(*ev));
2117
2118 opcode = __le16_to_cpu(ev->opcode);
2119
2120 switch (opcode) {
2121 case HCI_OP_INQUIRY_CANCEL:
2122 hci_cc_inquiry_cancel(hdev, skb);
2123 break;
2124
Andre Guedes4d934832012-03-21 00:03:35 -03002125 case HCI_OP_PERIODIC_INQ:
2126 hci_cc_periodic_inq(hdev, skb);
2127 break;
2128
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002129 case HCI_OP_EXIT_PERIODIC_INQ:
2130 hci_cc_exit_periodic_inq(hdev, skb);
2131 break;
2132
2133 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2134 hci_cc_remote_name_req_cancel(hdev, skb);
2135 break;
2136
2137 case HCI_OP_ROLE_DISCOVERY:
2138 hci_cc_role_discovery(hdev, skb);
2139 break;
2140
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002141 case HCI_OP_READ_LINK_POLICY:
2142 hci_cc_read_link_policy(hdev, skb);
2143 break;
2144
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002145 case HCI_OP_WRITE_LINK_POLICY:
2146 hci_cc_write_link_policy(hdev, skb);
2147 break;
2148
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002149 case HCI_OP_READ_DEF_LINK_POLICY:
2150 hci_cc_read_def_link_policy(hdev, skb);
2151 break;
2152
2153 case HCI_OP_WRITE_DEF_LINK_POLICY:
2154 hci_cc_write_def_link_policy(hdev, skb);
2155 break;
2156
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002157 case HCI_OP_RESET:
2158 hci_cc_reset(hdev, skb);
2159 break;
2160
2161 case HCI_OP_WRITE_LOCAL_NAME:
2162 hci_cc_write_local_name(hdev, skb);
2163 break;
2164
2165 case HCI_OP_READ_LOCAL_NAME:
2166 hci_cc_read_local_name(hdev, skb);
2167 break;
2168
2169 case HCI_OP_WRITE_AUTH_ENABLE:
2170 hci_cc_write_auth_enable(hdev, skb);
2171 break;
2172
2173 case HCI_OP_WRITE_ENCRYPT_MODE:
2174 hci_cc_write_encrypt_mode(hdev, skb);
2175 break;
2176
2177 case HCI_OP_WRITE_SCAN_ENABLE:
2178 hci_cc_write_scan_enable(hdev, skb);
2179 break;
2180
2181 case HCI_OP_READ_CLASS_OF_DEV:
2182 hci_cc_read_class_of_dev(hdev, skb);
2183 break;
2184
2185 case HCI_OP_WRITE_CLASS_OF_DEV:
2186 hci_cc_write_class_of_dev(hdev, skb);
2187 break;
2188
2189 case HCI_OP_READ_VOICE_SETTING:
2190 hci_cc_read_voice_setting(hdev, skb);
2191 break;
2192
2193 case HCI_OP_WRITE_VOICE_SETTING:
2194 hci_cc_write_voice_setting(hdev, skb);
2195 break;
2196
Marcel Holtmann333140b2008-07-14 20:13:48 +02002197 case HCI_OP_WRITE_SSP_MODE:
2198 hci_cc_write_ssp_mode(hdev, skb);
2199 break;
2200
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002201 case HCI_OP_READ_LOCAL_VERSION:
2202 hci_cc_read_local_version(hdev, skb);
2203 break;
2204
2205 case HCI_OP_READ_LOCAL_COMMANDS:
2206 hci_cc_read_local_commands(hdev, skb);
2207 break;
2208
2209 case HCI_OP_READ_LOCAL_FEATURES:
2210 hci_cc_read_local_features(hdev, skb);
2211 break;
2212
Andre Guedes971e3a42011-06-30 19:20:52 -03002213 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2214 hci_cc_read_local_ext_features(hdev, skb);
2215 break;
2216
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002217 case HCI_OP_READ_BUFFER_SIZE:
2218 hci_cc_read_buffer_size(hdev, skb);
2219 break;
2220
2221 case HCI_OP_READ_BD_ADDR:
2222 hci_cc_read_bd_addr(hdev, skb);
2223 break;
2224
Johan Hedbergf332ec62013-03-15 17:07:11 -05002225 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2226 hci_cc_read_page_scan_activity(hdev, skb);
2227 break;
2228
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002229 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2230 hci_cc_write_page_scan_activity(hdev, skb);
2231 break;
2232
Johan Hedbergf332ec62013-03-15 17:07:11 -05002233 case HCI_OP_READ_PAGE_SCAN_TYPE:
2234 hci_cc_read_page_scan_type(hdev, skb);
2235 break;
2236
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002237 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2238 hci_cc_write_page_scan_type(hdev, skb);
2239 break;
2240
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002241 case HCI_OP_READ_DATA_BLOCK_SIZE:
2242 hci_cc_read_data_block_size(hdev, skb);
2243 break;
2244
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002245 case HCI_OP_READ_FLOW_CONTROL_MODE:
2246 hci_cc_read_flow_control_mode(hdev, skb);
2247 break;
2248
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002249 case HCI_OP_READ_LOCAL_AMP_INFO:
2250 hci_cc_read_local_amp_info(hdev, skb);
2251 break;
2252
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002253 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2254 hci_cc_read_local_amp_assoc(hdev, skb);
2255 break;
2256
Johan Hedbergd5859e22011-01-25 01:19:58 +02002257 case HCI_OP_READ_INQ_RSP_TX_POWER:
2258 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2259 break;
2260
Johan Hedberg980e1a52011-01-22 06:10:07 +02002261 case HCI_OP_PIN_CODE_REPLY:
2262 hci_cc_pin_code_reply(hdev, skb);
2263 break;
2264
2265 case HCI_OP_PIN_CODE_NEG_REPLY:
2266 hci_cc_pin_code_neg_reply(hdev, skb);
2267 break;
2268
Szymon Jancc35938b2011-03-22 13:12:21 +01002269 case HCI_OP_READ_LOCAL_OOB_DATA:
2270 hci_cc_read_local_oob_data_reply(hdev, skb);
2271 break;
2272
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002273 case HCI_OP_LE_READ_BUFFER_SIZE:
2274 hci_cc_le_read_buffer_size(hdev, skb);
2275 break;
2276
Johan Hedberg60e77322013-01-22 14:01:59 +02002277 case HCI_OP_LE_READ_LOCAL_FEATURES:
2278 hci_cc_le_read_local_features(hdev, skb);
2279 break;
2280
Johan Hedberg8fa19092012-10-19 20:57:49 +03002281 case HCI_OP_LE_READ_ADV_TX_POWER:
2282 hci_cc_le_read_adv_tx_power(hdev, skb);
2283 break;
2284
Johan Hedberga5c29682011-02-19 12:05:57 -03002285 case HCI_OP_USER_CONFIRM_REPLY:
2286 hci_cc_user_confirm_reply(hdev, skb);
2287 break;
2288
2289 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2290 hci_cc_user_confirm_neg_reply(hdev, skb);
2291 break;
2292
Brian Gix1143d452011-11-23 08:28:34 -08002293 case HCI_OP_USER_PASSKEY_REPLY:
2294 hci_cc_user_passkey_reply(hdev, skb);
2295 break;
2296
2297 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2298 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002299 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002300
2301 case HCI_OP_LE_SET_SCAN_PARAM:
2302 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002303 break;
2304
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002305 case HCI_OP_LE_SET_ADV_ENABLE:
2306 hci_cc_le_set_adv_enable(hdev, skb);
2307 break;
2308
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002309 case HCI_OP_LE_SET_SCAN_ENABLE:
2310 hci_cc_le_set_scan_enable(hdev, skb);
2311 break;
2312
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002313 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2314 hci_cc_le_read_white_list_size(hdev, skb);
2315 break;
2316
Johan Hedberg9b008c02013-01-22 14:02:01 +02002317 case HCI_OP_LE_READ_SUPPORTED_STATES:
2318 hci_cc_le_read_supported_states(hdev, skb);
2319 break;
2320
Andre Guedesf9b49302011-06-30 19:20:53 -03002321 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2322 hci_cc_write_le_host_supported(hdev, skb);
2323 break;
2324
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002325 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2326 hci_cc_write_remote_amp_assoc(hdev, skb);
2327 break;
2328
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002329 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002330 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002331 break;
2332 }
2333
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002334 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002335 del_timer(&hdev->cmd_timer);
2336
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002337 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002338
Szymon Jancdbccd792012-12-11 08:51:19 +01002339 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002340 atomic_set(&hdev->cmd_cnt, 1);
2341 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002342 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002343 }
2344}
2345
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002346static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002347{
2348 struct hci_ev_cmd_status *ev = (void *) skb->data;
2349 __u16 opcode;
2350
2351 skb_pull(skb, sizeof(*ev));
2352
2353 opcode = __le16_to_cpu(ev->opcode);
2354
2355 switch (opcode) {
2356 case HCI_OP_INQUIRY:
2357 hci_cs_inquiry(hdev, ev->status);
2358 break;
2359
2360 case HCI_OP_CREATE_CONN:
2361 hci_cs_create_conn(hdev, ev->status);
2362 break;
2363
2364 case HCI_OP_ADD_SCO:
2365 hci_cs_add_sco(hdev, ev->status);
2366 break;
2367
Marcel Holtmannf8558552008-07-14 20:13:49 +02002368 case HCI_OP_AUTH_REQUESTED:
2369 hci_cs_auth_requested(hdev, ev->status);
2370 break;
2371
2372 case HCI_OP_SET_CONN_ENCRYPT:
2373 hci_cs_set_conn_encrypt(hdev, ev->status);
2374 break;
2375
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002376 case HCI_OP_REMOTE_NAME_REQ:
2377 hci_cs_remote_name_req(hdev, ev->status);
2378 break;
2379
Marcel Holtmann769be972008-07-14 20:13:49 +02002380 case HCI_OP_READ_REMOTE_FEATURES:
2381 hci_cs_read_remote_features(hdev, ev->status);
2382 break;
2383
2384 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2385 hci_cs_read_remote_ext_features(hdev, ev->status);
2386 break;
2387
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002388 case HCI_OP_SETUP_SYNC_CONN:
2389 hci_cs_setup_sync_conn(hdev, ev->status);
2390 break;
2391
2392 case HCI_OP_SNIFF_MODE:
2393 hci_cs_sniff_mode(hdev, ev->status);
2394 break;
2395
2396 case HCI_OP_EXIT_SNIFF_MODE:
2397 hci_cs_exit_sniff_mode(hdev, ev->status);
2398 break;
2399
Johan Hedberg8962ee72011-01-20 12:40:27 +02002400 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002401 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002402 break;
2403
Ville Tervofcd89c02011-02-10 22:38:47 -03002404 case HCI_OP_LE_CREATE_CONN:
2405 hci_cs_le_create_conn(hdev, ev->status);
2406 break;
2407
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002408 case HCI_OP_CREATE_PHY_LINK:
2409 hci_cs_create_phylink(hdev, ev->status);
2410 break;
2411
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002412 case HCI_OP_ACCEPT_PHY_LINK:
2413 hci_cs_accept_phylink(hdev, ev->status);
2414 break;
2415
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002416 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002417 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002418 break;
2419 }
2420
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002421 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002422 del_timer(&hdev->cmd_timer);
2423
Johan Hedberg02350a72013-04-03 21:50:29 +03002424 if (ev->status ||
2425 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2426 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002427
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002428 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002429 atomic_set(&hdev->cmd_cnt, 1);
2430 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002431 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002432 }
2433}
2434
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002435static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002436{
2437 struct hci_ev_role_change *ev = (void *) skb->data;
2438 struct hci_conn *conn;
2439
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002440 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002441
2442 hci_dev_lock(hdev);
2443
2444 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2445 if (conn) {
2446 if (!ev->status) {
2447 if (ev->role)
2448 conn->link_mode &= ~HCI_LM_MASTER;
2449 else
2450 conn->link_mode |= HCI_LM_MASTER;
2451 }
2452
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002453 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002454
2455 hci_role_switch_cfm(conn, ev->status, ev->role);
2456 }
2457
2458 hci_dev_unlock(hdev);
2459}
2460
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002461static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002462{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002463 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002464 int i;
2465
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002466 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2467 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2468 return;
2469 }
2470
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002471 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002472 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473 BT_DBG("%s bad parameters", hdev->name);
2474 return;
2475 }
2476
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002477 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2478
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002479 for (i = 0; i < ev->num_hndl; i++) {
2480 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002481 struct hci_conn *conn;
2482 __u16 handle, count;
2483
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002484 handle = __le16_to_cpu(info->handle);
2485 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486
2487 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002488 if (!conn)
2489 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002490
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002491 conn->sent -= count;
2492
2493 switch (conn->type) {
2494 case ACL_LINK:
2495 hdev->acl_cnt += count;
2496 if (hdev->acl_cnt > hdev->acl_pkts)
2497 hdev->acl_cnt = hdev->acl_pkts;
2498 break;
2499
2500 case LE_LINK:
2501 if (hdev->le_pkts) {
2502 hdev->le_cnt += count;
2503 if (hdev->le_cnt > hdev->le_pkts)
2504 hdev->le_cnt = hdev->le_pkts;
2505 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002506 hdev->acl_cnt += count;
2507 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508 hdev->acl_cnt = hdev->acl_pkts;
2509 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002510 break;
2511
2512 case SCO_LINK:
2513 hdev->sco_cnt += count;
2514 if (hdev->sco_cnt > hdev->sco_pkts)
2515 hdev->sco_cnt = hdev->sco_pkts;
2516 break;
2517
2518 default:
2519 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2520 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002521 }
2522 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002523
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002524 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525}
2526
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002527static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2528 __u16 handle)
2529{
2530 struct hci_chan *chan;
2531
2532 switch (hdev->dev_type) {
2533 case HCI_BREDR:
2534 return hci_conn_hash_lookup_handle(hdev, handle);
2535 case HCI_AMP:
2536 chan = hci_chan_lookup_handle(hdev, handle);
2537 if (chan)
2538 return chan->conn;
2539 break;
2540 default:
2541 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2542 break;
2543 }
2544
2545 return NULL;
2546}
2547
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002548static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002549{
2550 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2551 int i;
2552
2553 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2554 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2555 return;
2556 }
2557
2558 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002559 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002560 BT_DBG("%s bad parameters", hdev->name);
2561 return;
2562 }
2563
2564 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002565 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002566
2567 for (i = 0; i < ev->num_hndl; i++) {
2568 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002569 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002570 __u16 handle, block_count;
2571
2572 handle = __le16_to_cpu(info->handle);
2573 block_count = __le16_to_cpu(info->blocks);
2574
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002575 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002576 if (!conn)
2577 continue;
2578
2579 conn->sent -= block_count;
2580
2581 switch (conn->type) {
2582 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002583 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002584 hdev->block_cnt += block_count;
2585 if (hdev->block_cnt > hdev->num_blocks)
2586 hdev->block_cnt = hdev->num_blocks;
2587 break;
2588
2589 default:
2590 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2591 break;
2592 }
2593 }
2594
2595 queue_work(hdev->workqueue, &hdev->tx_work);
2596}
2597
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002598static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002599{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002600 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002601 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002603 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604
2605 hci_dev_lock(hdev);
2606
Marcel Holtmann04837f62006-07-03 10:02:33 +02002607 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2608 if (conn) {
2609 conn->mode = ev->mode;
2610 conn->interval = __le16_to_cpu(ev->interval);
2611
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002612 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2613 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002614 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002615 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002616 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002617 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002618 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002619
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002620 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002621 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002622 }
2623
2624 hci_dev_unlock(hdev);
2625}
2626
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002627static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002629 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2630 struct hci_conn *conn;
2631
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002632 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002633
2634 hci_dev_lock(hdev);
2635
2636 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002637 if (!conn)
2638 goto unlock;
2639
2640 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002641 hci_conn_hold(conn);
2642 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002643 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002644 }
2645
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002646 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002647 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002648 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002649 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002650 u8 secure;
2651
2652 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2653 secure = 1;
2654 else
2655 secure = 0;
2656
Johan Hedberg744cf192011-11-08 20:40:14 +02002657 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002658 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002659
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002660unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002661 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662}
2663
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002664static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002666 struct hci_ev_link_key_req *ev = (void *) skb->data;
2667 struct hci_cp_link_key_reply cp;
2668 struct hci_conn *conn;
2669 struct link_key *key;
2670
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002671 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002672
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002673 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002674 return;
2675
2676 hci_dev_lock(hdev);
2677
2678 key = hci_find_link_key(hdev, &ev->bdaddr);
2679 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002680 BT_DBG("%s link key not found for %pMR", hdev->name,
2681 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002682 goto not_found;
2683 }
2684
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002685 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2686 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002687
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002688 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002689 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002690 BT_DBG("%s ignoring debug key", hdev->name);
2691 goto not_found;
2692 }
2693
2694 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002695 if (conn) {
2696 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002697 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002698 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2699 goto not_found;
2700 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002701
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002702 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002703 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002704 BT_DBG("%s ignoring key unauthenticated for high security",
2705 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002706 goto not_found;
2707 }
2708
2709 conn->key_type = key->type;
2710 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002711 }
2712
2713 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002714 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002715
2716 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2717
2718 hci_dev_unlock(hdev);
2719
2720 return;
2721
2722not_found:
2723 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2724 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725}
2726
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002727static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002729 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2730 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002731 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002732
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002733 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002734
2735 hci_dev_lock(hdev);
2736
2737 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2738 if (conn) {
2739 hci_conn_hold(conn);
2740 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002741 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002742
2743 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2744 conn->key_type = ev->key_type;
2745
David Herrmann76a68ba2013-04-06 20:28:37 +02002746 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002747 }
2748
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002749 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002750 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002751 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002752
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002753 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754}
2755
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002756static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002757{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002758 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002759 struct hci_conn *conn;
2760
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002761 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002762
2763 hci_dev_lock(hdev);
2764
2765 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002766 if (conn && !ev->status) {
2767 struct inquiry_entry *ie;
2768
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002769 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2770 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002771 ie->data.clock_offset = ev->clock_offset;
2772 ie->timestamp = jiffies;
2773 }
2774 }
2775
2776 hci_dev_unlock(hdev);
2777}
2778
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002779static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002780{
2781 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2782 struct hci_conn *conn;
2783
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002784 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002785
2786 hci_dev_lock(hdev);
2787
2788 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2789 if (conn && !ev->status)
2790 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2791
2792 hci_dev_unlock(hdev);
2793}
2794
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002795static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002796{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002797 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002798 struct inquiry_entry *ie;
2799
2800 BT_DBG("%s", hdev->name);
2801
2802 hci_dev_lock(hdev);
2803
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002804 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2805 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002806 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2807 ie->timestamp = jiffies;
2808 }
2809
2810 hci_dev_unlock(hdev);
2811}
2812
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002813static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2814 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002815{
2816 struct inquiry_data data;
2817 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002818 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002819
2820 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2821
2822 if (!num_rsp)
2823 return;
2824
Andre Guedes1519cc12012-03-21 00:03:38 -03002825 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2826 return;
2827
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002828 hci_dev_lock(hdev);
2829
2830 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002831 struct inquiry_info_with_rssi_and_pscan_mode *info;
2832 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002833
Johan Hedberge17acd42011-03-30 23:57:16 +03002834 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002835 bacpy(&data.bdaddr, &info->bdaddr);
2836 data.pscan_rep_mode = info->pscan_rep_mode;
2837 data.pscan_period_mode = info->pscan_period_mode;
2838 data.pscan_mode = info->pscan_mode;
2839 memcpy(data.dev_class, info->dev_class, 3);
2840 data.clock_offset = info->clock_offset;
2841 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002842 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002843
2844 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002845 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002846 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002847 info->dev_class, info->rssi,
2848 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002849 }
2850 } else {
2851 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2852
Johan Hedberge17acd42011-03-30 23:57:16 +03002853 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002854 bacpy(&data.bdaddr, &info->bdaddr);
2855 data.pscan_rep_mode = info->pscan_rep_mode;
2856 data.pscan_period_mode = info->pscan_period_mode;
2857 data.pscan_mode = 0x00;
2858 memcpy(data.dev_class, info->dev_class, 3);
2859 data.clock_offset = info->clock_offset;
2860 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002861 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002862 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002863 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002864 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002865 info->dev_class, info->rssi,
2866 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002867 }
2868 }
2869
2870 hci_dev_unlock(hdev);
2871}
2872
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002873static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2874 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002875{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002876 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2877 struct hci_conn *conn;
2878
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002879 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002880
Marcel Holtmann41a96212008-07-14 20:13:48 +02002881 hci_dev_lock(hdev);
2882
2883 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002884 if (!conn)
2885 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002886
Johan Hedbergcad718e2013-04-17 15:00:51 +03002887 if (ev->page < HCI_MAX_PAGES)
2888 memcpy(conn->features[ev->page], ev->features, 8);
2889
Johan Hedbergccd556f2010-11-10 17:11:51 +02002890 if (!ev->status && ev->page == 0x01) {
2891 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002892
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002893 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2894 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002895 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002896
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302897 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002898 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302899 } else {
2900 /* It is mandatory by the Bluetooth specification that
2901 * Extended Inquiry Results are only used when Secure
2902 * Simple Pairing is enabled, but some devices violate
2903 * this.
2904 *
2905 * To make these devices work, the internal SSP
2906 * enabled flag needs to be cleared if the remote host
2907 * features do not indicate SSP support */
2908 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2909 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002910 }
2911
Johan Hedbergccd556f2010-11-10 17:11:51 +02002912 if (conn->state != BT_CONFIG)
2913 goto unlock;
2914
Johan Hedberg671267b2012-05-12 16:11:50 -03002915 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002916 struct hci_cp_remote_name_req cp;
2917 memset(&cp, 0, sizeof(cp));
2918 bacpy(&cp.bdaddr, &conn->dst);
2919 cp.pscan_rep_mode = 0x02;
2920 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002921 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2922 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002923 conn->dst_type, 0, NULL, 0,
2924 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002925
Johan Hedberg127178d2010-11-18 22:22:29 +02002926 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002927 conn->state = BT_CONNECTED;
2928 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002929 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002930 }
2931
2932unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002933 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002934}
2935
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002936static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2937 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002938{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002939 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2940 struct hci_conn *conn;
2941
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002942 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002943
2944 hci_dev_lock(hdev);
2945
2946 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002947 if (!conn) {
2948 if (ev->link_type == ESCO_LINK)
2949 goto unlock;
2950
2951 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2952 if (!conn)
2953 goto unlock;
2954
2955 conn->type = SCO_LINK;
2956 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002957
Marcel Holtmann732547f2009-04-19 19:14:14 +02002958 switch (ev->status) {
2959 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002960 conn->handle = __le16_to_cpu(ev->handle);
2961 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002962
2963 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002964 break;
2965
Stephen Coe705e5712010-02-16 11:29:44 -05002966 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002967 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002968 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002969 case 0x1f: /* Unspecified error */
2970 if (conn->out && conn->attempt < 2) {
2971 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2972 (hdev->esco_type & EDR_ESCO_MASK);
2973 hci_setup_sync(conn, conn->link->handle);
2974 goto unlock;
2975 }
2976 /* fall through */
2977
2978 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002979 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002980 break;
2981 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002982
2983 hci_proto_connect_cfm(conn, ev->status);
2984 if (ev->status)
2985 hci_conn_del(conn);
2986
2987unlock:
2988 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002989}
2990
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002991static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2992 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002993{
2994 struct inquiry_data data;
2995 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2996 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302997 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002998
2999 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3000
3001 if (!num_rsp)
3002 return;
3003
Andre Guedes1519cc12012-03-21 00:03:38 -03003004 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3005 return;
3006
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003007 hci_dev_lock(hdev);
3008
Johan Hedberge17acd42011-03-30 23:57:16 +03003009 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003010 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003011
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003012 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003013 data.pscan_rep_mode = info->pscan_rep_mode;
3014 data.pscan_period_mode = info->pscan_period_mode;
3015 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003016 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003017 data.clock_offset = info->clock_offset;
3018 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003019 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003020
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003021 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003022 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003023 sizeof(info->data),
3024 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003025 else
3026 name_known = true;
3027
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003028 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003029 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303030 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003031 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003032 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303033 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003034 }
3035
3036 hci_dev_unlock(hdev);
3037}
3038
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003039static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3040 struct sk_buff *skb)
3041{
3042 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3043 struct hci_conn *conn;
3044
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003045 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003046 __le16_to_cpu(ev->handle));
3047
3048 hci_dev_lock(hdev);
3049
3050 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3051 if (!conn)
3052 goto unlock;
3053
Johan Hedberg2ef1b8b2014-04-11 12:02:31 -07003054 /* For BR/EDR the necessary steps are taken through the
3055 * auth_complete event.
3056 */
3057 if (conn->type != LE_LINK)
3058 goto unlock;
3059
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003060 if (!ev->status)
3061 conn->sec_level = conn->pending_sec_level;
3062
3063 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3064
3065 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003066 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003067 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003068 goto unlock;
3069 }
3070
3071 if (conn->state == BT_CONFIG) {
3072 if (!ev->status)
3073 conn->state = BT_CONNECTED;
3074
3075 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003076 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003077 } else {
3078 hci_auth_cfm(conn, ev->status);
3079
3080 hci_conn_hold(conn);
3081 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003082 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003083 }
3084
3085unlock:
3086 hci_dev_unlock(hdev);
3087}
3088
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003089static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003090{
3091 /* If remote requests dedicated bonding follow that lead */
3092 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3093 /* If both remote and local IO capabilities allow MITM
3094 * protection then require it, otherwise don't */
3095 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3096 return 0x02;
3097 else
3098 return 0x03;
3099 }
3100
3101 /* If remote requests no-bonding follow that lead */
3102 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003103 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003104
3105 return conn->auth_type;
3106}
3107
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003108static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003109{
3110 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3111 struct hci_conn *conn;
3112
3113 BT_DBG("%s", hdev->name);
3114
3115 hci_dev_lock(hdev);
3116
3117 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003118 if (!conn)
3119 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003120
Johan Hedberg03b555e2011-01-04 15:40:05 +02003121 hci_conn_hold(conn);
3122
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003123 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003124 goto unlock;
3125
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003126 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003127 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003128 struct hci_cp_io_capability_reply cp;
3129
3130 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303131 /* Change the IO capability from KeyboardDisplay
3132 * to DisplayYesNo as it is not supported by BT spec. */
3133 cp.capability = (conn->io_capability == 0x04) ?
3134 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003135 conn->auth_type = hci_get_auth_req(conn);
3136 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003137
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003138 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3139 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003140 cp.oob_data = 0x01;
3141 else
3142 cp.oob_data = 0x00;
3143
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003144 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003145 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003146 } else {
3147 struct hci_cp_io_capability_neg_reply cp;
3148
3149 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003150 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003151
3152 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003153 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003154 }
3155
3156unlock:
3157 hci_dev_unlock(hdev);
3158}
3159
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003160static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003161{
3162 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3163 struct hci_conn *conn;
3164
3165 BT_DBG("%s", hdev->name);
3166
3167 hci_dev_lock(hdev);
3168
3169 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3170 if (!conn)
3171 goto unlock;
3172
Johan Hedberg03b555e2011-01-04 15:40:05 +02003173 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003174 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003175 if (ev->oob_data)
3176 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003177
3178unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003179 hci_dev_unlock(hdev);
3180}
3181
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003182static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3183 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003184{
3185 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003186 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003187 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003188
3189 BT_DBG("%s", hdev->name);
3190
3191 hci_dev_lock(hdev);
3192
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003193 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003194 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003195
Johan Hedberg7a828902011-04-28 11:28:53 -07003196 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3197 if (!conn)
3198 goto unlock;
3199
3200 loc_mitm = (conn->auth_type & 0x01);
3201 rem_mitm = (conn->remote_auth & 0x01);
3202
3203 /* If we require MITM but the remote device can't provide that
3204 * (it has NoInputNoOutput) then reject the confirmation
3205 * request. The only exception is when we're dedicated bonding
3206 * initiators (connect_cfm_cb set) since then we always have the MITM
3207 * bit set. */
3208 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3209 BT_DBG("Rejecting request: remote device can't provide MITM");
3210 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003211 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003212 goto unlock;
3213 }
3214
3215 /* If no side requires MITM protection; auto-accept */
3216 if ((!loc_mitm || conn->remote_cap == 0x03) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003217 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003218
3219 /* If we're not the initiators request authorization to
3220 * proceed from user space (mgmt_user_confirm with
Johan Hedberg6ab84782014-06-09 13:58:14 +03003221 * confirm_hint set to 1). The exception is if neither
3222 * side had MITM in which case we do auto-accept.
3223 */
3224 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
3225 (loc_mitm || rem_mitm)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003226 BT_DBG("Confirming auto-accept as acceptor");
3227 confirm_hint = 1;
3228 goto confirm;
3229 }
3230
Johan Hedberg9f616562011-04-28 11:28:54 -07003231 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003232 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003233
3234 if (hdev->auto_accept_delay > 0) {
3235 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3236 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3237 goto unlock;
3238 }
3239
Johan Hedberg7a828902011-04-28 11:28:53 -07003240 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003241 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003242 goto unlock;
3243 }
3244
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003245confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003246 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003247 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003248
3249unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003250 hci_dev_unlock(hdev);
3251}
3252
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003253static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3254 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003255{
3256 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3257
3258 BT_DBG("%s", hdev->name);
3259
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003260 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003261 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003262}
3263
Johan Hedberg92a25252012-09-06 18:39:26 +03003264static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3265 struct sk_buff *skb)
3266{
3267 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3268 struct hci_conn *conn;
3269
3270 BT_DBG("%s", hdev->name);
3271
3272 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3273 if (!conn)
3274 return;
3275
3276 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3277 conn->passkey_entered = 0;
3278
3279 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3280 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3281 conn->dst_type, conn->passkey_notify,
3282 conn->passkey_entered);
3283}
3284
3285static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3286{
3287 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3288 struct hci_conn *conn;
3289
3290 BT_DBG("%s", hdev->name);
3291
3292 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3293 if (!conn)
3294 return;
3295
3296 switch (ev->type) {
3297 case HCI_KEYPRESS_STARTED:
3298 conn->passkey_entered = 0;
3299 return;
3300
3301 case HCI_KEYPRESS_ENTERED:
3302 conn->passkey_entered++;
3303 break;
3304
3305 case HCI_KEYPRESS_ERASED:
3306 conn->passkey_entered--;
3307 break;
3308
3309 case HCI_KEYPRESS_CLEARED:
3310 conn->passkey_entered = 0;
3311 break;
3312
3313 case HCI_KEYPRESS_COMPLETED:
3314 return;
3315 }
3316
3317 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3318 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3319 conn->dst_type, conn->passkey_notify,
3320 conn->passkey_entered);
3321}
3322
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003323static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3324 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003325{
3326 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3327 struct hci_conn *conn;
3328
3329 BT_DBG("%s", hdev->name);
3330
3331 hci_dev_lock(hdev);
3332
3333 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003334 if (!conn)
3335 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003336
Johan Hedberg2a611692011-02-19 12:06:00 -03003337 /* To avoid duplicate auth_failed events to user space we check
3338 * the HCI_CONN_AUTH_PEND flag which will be set if we
3339 * initiated the authentication. A traditional auth_complete
3340 * event gets always produced as initiator and is also mapped to
3341 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003342 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003343 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003344 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003345
David Herrmann76a68ba2013-04-06 20:28:37 +02003346 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003347
3348unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003349 hci_dev_unlock(hdev);
3350}
3351
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003352static void hci_remote_host_features_evt(struct hci_dev *hdev,
3353 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003354{
3355 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3356 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003357 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003358
3359 BT_DBG("%s", hdev->name);
3360
3361 hci_dev_lock(hdev);
3362
Johan Hedbergcad718e2013-04-17 15:00:51 +03003363 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3364 if (conn)
3365 memcpy(conn->features[1], ev->features, 8);
3366
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003367 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3368 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003369 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003370
3371 hci_dev_unlock(hdev);
3372}
3373
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003374static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3375 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003376{
3377 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3378 struct oob_data *data;
3379
3380 BT_DBG("%s", hdev->name);
3381
3382 hci_dev_lock(hdev);
3383
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003384 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003385 goto unlock;
3386
Szymon Janc2763eda2011-03-22 13:12:22 +01003387 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3388 if (data) {
3389 struct hci_cp_remote_oob_data_reply cp;
3390
3391 bacpy(&cp.bdaddr, &ev->bdaddr);
3392 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3393 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3394
3395 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003396 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003397 } else {
3398 struct hci_cp_remote_oob_data_neg_reply cp;
3399
3400 bacpy(&cp.bdaddr, &ev->bdaddr);
3401 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003402 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003403 }
3404
Szymon Jance1ba1f12011-04-06 13:01:59 +02003405unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003406 hci_dev_unlock(hdev);
3407}
3408
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003409static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3410 struct sk_buff *skb)
3411{
3412 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3413 struct hci_conn *hcon, *bredr_hcon;
3414
3415 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3416 ev->status);
3417
3418 hci_dev_lock(hdev);
3419
3420 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3421 if (!hcon) {
3422 hci_dev_unlock(hdev);
3423 return;
3424 }
3425
3426 if (ev->status) {
3427 hci_conn_del(hcon);
3428 hci_dev_unlock(hdev);
3429 return;
3430 }
3431
3432 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3433
3434 hcon->state = BT_CONNECTED;
3435 bacpy(&hcon->dst, &bredr_hcon->dst);
3436
3437 hci_conn_hold(hcon);
3438 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003439 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003440
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003441 hci_conn_add_sysfs(hcon);
3442
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003443 amp_physical_cfm(bredr_hcon, hcon);
3444
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003445 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003446}
3447
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003448static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3449{
3450 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3451 struct hci_conn *hcon;
3452 struct hci_chan *hchan;
3453 struct amp_mgr *mgr;
3454
3455 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3456 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3457 ev->status);
3458
3459 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3460 if (!hcon)
3461 return;
3462
3463 /* Create AMP hchan */
3464 hchan = hci_chan_create(hcon);
3465 if (!hchan)
3466 return;
3467
3468 hchan->handle = le16_to_cpu(ev->handle);
3469
3470 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3471
3472 mgr = hcon->amp_mgr;
3473 if (mgr && mgr->bredr_chan) {
3474 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3475
3476 l2cap_chan_lock(bredr_chan);
3477
3478 bredr_chan->conn->mtu = hdev->block_mtu;
3479 l2cap_logical_cfm(bredr_chan, hchan, 0);
3480 hci_conn_hold(hcon);
3481
3482 l2cap_chan_unlock(bredr_chan);
3483 }
3484}
3485
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003486static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3487 struct sk_buff *skb)
3488{
3489 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3490 struct hci_chan *hchan;
3491
3492 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3493 le16_to_cpu(ev->handle), ev->status);
3494
3495 if (ev->status)
3496 return;
3497
3498 hci_dev_lock(hdev);
3499
3500 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3501 if (!hchan)
3502 goto unlock;
3503
3504 amp_destroy_logical_link(hchan, ev->reason);
3505
3506unlock:
3507 hci_dev_unlock(hdev);
3508}
3509
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003510static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3511 struct sk_buff *skb)
3512{
3513 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3514 struct hci_conn *hcon;
3515
3516 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3517
3518 if (ev->status)
3519 return;
3520
3521 hci_dev_lock(hdev);
3522
3523 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3524 if (hcon) {
3525 hcon->state = BT_CLOSED;
3526 hci_conn_del(hcon);
3527 }
3528
3529 hci_dev_unlock(hdev);
3530}
3531
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003532static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003533{
3534 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3535 struct hci_conn *conn;
3536
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003537 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003538
3539 hci_dev_lock(hdev);
3540
Andre Guedesb47a09b2012-07-27 15:10:15 -03003541 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003542 if (!conn) {
3543 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3544 if (!conn) {
3545 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003546 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003547 }
Andre Guedes29b79882011-05-31 14:20:54 -03003548
3549 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003550
3551 if (ev->role == LE_CONN_ROLE_MASTER) {
3552 conn->out = true;
3553 conn->link_mode |= HCI_LM_MASTER;
3554 }
Ville Tervob62f3282011-02-10 22:38:50 -03003555 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003556
Andre Guedescd17dec2012-07-27 15:10:16 -03003557 if (ev->status) {
3558 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3559 conn->dst_type, ev->status);
3560 hci_proto_connect_cfm(conn, ev->status);
3561 conn->state = BT_CLOSED;
3562 hci_conn_del(conn);
3563 goto unlock;
3564 }
3565
Johan Hedbergb644ba32012-01-17 21:48:47 +02003566 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3567 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003568 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003569
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003570 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003571 conn->handle = __le16_to_cpu(ev->handle);
3572 conn->state = BT_CONNECTED;
3573
Ville Tervofcd89c02011-02-10 22:38:47 -03003574 hci_conn_add_sysfs(conn);
3575
3576 hci_proto_connect_cfm(conn, ev->status);
3577
3578unlock:
3579 hci_dev_unlock(hdev);
3580}
3581
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003582static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003583{
Andre Guedese95beb42011-09-26 20:48:35 -03003584 u8 num_reports = skb->data[0];
3585 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003586 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003587
Andre Guedese95beb42011-09-26 20:48:35 -03003588 while (num_reports--) {
3589 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003590
Andre Guedes3c9e9192012-01-10 18:20:50 -03003591 rssi = ev->data[ev->length];
3592 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003593 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003594
Andre Guedese95beb42011-09-26 20:48:35 -03003595 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003596 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003597}
3598
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003599static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003600{
3601 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3602 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003603 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003604 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003605 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003606
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003607 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003608
3609 hci_dev_lock(hdev);
3610
3611 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003612 if (conn == NULL)
3613 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003614
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003615 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3616 if (ltk == NULL)
3617 goto not_found;
3618
3619 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003620 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003621
3622 if (ltk->authenticated)
Andre Guedesa508ba22013-07-31 16:25:28 -03003623 conn->pending_sec_level = BT_SECURITY_HIGH;
3624 else
3625 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003626
Andre Guedesad04e6c2013-07-31 16:25:29 -03003627 conn->enc_key_size = ltk->enc_size;
3628
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003629 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3630
Claudio Takahasi2dbecc72013-07-25 16:34:24 -03003631 /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
3632 * temporary key used to encrypt a connection following
3633 * pairing. It is used during the Encrypted Session Setup to
3634 * distribute the keys. Later, security can be re-established
3635 * using a distributed LTK.
3636 */
3637 if (ltk->type == HCI_SMP_STK_SLAVE) {
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003638 list_del(&ltk->list);
3639 kfree(ltk);
3640 }
3641
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003642 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003643
3644 return;
3645
3646not_found:
3647 neg.handle = ev->handle;
3648 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3649 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003650}
3651
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003652static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003653{
3654 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3655
3656 skb_pull(skb, sizeof(*le_ev));
3657
3658 switch (le_ev->subevent) {
3659 case HCI_EV_LE_CONN_COMPLETE:
3660 hci_le_conn_complete_evt(hdev, skb);
3661 break;
3662
Andre Guedes9aa04c92011-05-26 16:23:51 -03003663 case HCI_EV_LE_ADVERTISING_REPORT:
3664 hci_le_adv_report_evt(hdev, skb);
3665 break;
3666
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003667 case HCI_EV_LE_LTK_REQ:
3668 hci_le_ltk_request_evt(hdev, skb);
3669 break;
3670
Ville Tervofcd89c02011-02-10 22:38:47 -03003671 default:
3672 break;
3673 }
3674}
3675
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003676static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3677{
3678 struct hci_ev_channel_selected *ev = (void *) skb->data;
3679 struct hci_conn *hcon;
3680
3681 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3682
3683 skb_pull(skb, sizeof(*ev));
3684
3685 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3686 if (!hcon)
3687 return;
3688
3689 amp_read_loc_assoc_final_data(hdev, hcon);
3690}
3691
Linus Torvalds1da177e2005-04-16 15:20:36 -07003692void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3693{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003694 struct hci_event_hdr *hdr = (void *) skb->data;
3695 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003696
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003697 hci_dev_lock(hdev);
3698
3699 /* Received events are (currently) only needed when a request is
3700 * ongoing so avoid unnecessary memory allocation.
3701 */
3702 if (hdev->req_status == HCI_REQ_PEND) {
3703 kfree_skb(hdev->recv_evt);
3704 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3705 }
3706
3707 hci_dev_unlock(hdev);
3708
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3710
Johan Hedberg02350a72013-04-03 21:50:29 +03003711 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
3712 struct hci_command_hdr *hdr = (void *) hdev->sent_cmd->data;
3713 u16 opcode = __le16_to_cpu(hdr->opcode);
3714
3715 hci_req_cmd_complete(hdev, opcode, 0);
3716 }
3717
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003718 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003719 case HCI_EV_INQUIRY_COMPLETE:
3720 hci_inquiry_complete_evt(hdev, skb);
3721 break;
3722
3723 case HCI_EV_INQUIRY_RESULT:
3724 hci_inquiry_result_evt(hdev, skb);
3725 break;
3726
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003727 case HCI_EV_CONN_COMPLETE:
3728 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003729 break;
3730
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731 case HCI_EV_CONN_REQUEST:
3732 hci_conn_request_evt(hdev, skb);
3733 break;
3734
Linus Torvalds1da177e2005-04-16 15:20:36 -07003735 case HCI_EV_DISCONN_COMPLETE:
3736 hci_disconn_complete_evt(hdev, skb);
3737 break;
3738
Linus Torvalds1da177e2005-04-16 15:20:36 -07003739 case HCI_EV_AUTH_COMPLETE:
3740 hci_auth_complete_evt(hdev, skb);
3741 break;
3742
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003743 case HCI_EV_REMOTE_NAME:
3744 hci_remote_name_evt(hdev, skb);
3745 break;
3746
Linus Torvalds1da177e2005-04-16 15:20:36 -07003747 case HCI_EV_ENCRYPT_CHANGE:
3748 hci_encrypt_change_evt(hdev, skb);
3749 break;
3750
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003751 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3752 hci_change_link_key_complete_evt(hdev, skb);
3753 break;
3754
3755 case HCI_EV_REMOTE_FEATURES:
3756 hci_remote_features_evt(hdev, skb);
3757 break;
3758
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003759 case HCI_EV_CMD_COMPLETE:
3760 hci_cmd_complete_evt(hdev, skb);
3761 break;
3762
3763 case HCI_EV_CMD_STATUS:
3764 hci_cmd_status_evt(hdev, skb);
3765 break;
3766
3767 case HCI_EV_ROLE_CHANGE:
3768 hci_role_change_evt(hdev, skb);
3769 break;
3770
3771 case HCI_EV_NUM_COMP_PKTS:
3772 hci_num_comp_pkts_evt(hdev, skb);
3773 break;
3774
3775 case HCI_EV_MODE_CHANGE:
3776 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003777 break;
3778
3779 case HCI_EV_PIN_CODE_REQ:
3780 hci_pin_code_request_evt(hdev, skb);
3781 break;
3782
3783 case HCI_EV_LINK_KEY_REQ:
3784 hci_link_key_request_evt(hdev, skb);
3785 break;
3786
3787 case HCI_EV_LINK_KEY_NOTIFY:
3788 hci_link_key_notify_evt(hdev, skb);
3789 break;
3790
3791 case HCI_EV_CLOCK_OFFSET:
3792 hci_clock_offset_evt(hdev, skb);
3793 break;
3794
Marcel Holtmanna8746412008-07-14 20:13:46 +02003795 case HCI_EV_PKT_TYPE_CHANGE:
3796 hci_pkt_type_change_evt(hdev, skb);
3797 break;
3798
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003799 case HCI_EV_PSCAN_REP_MODE:
3800 hci_pscan_rep_mode_evt(hdev, skb);
3801 break;
3802
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003803 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3804 hci_inquiry_result_with_rssi_evt(hdev, skb);
3805 break;
3806
3807 case HCI_EV_REMOTE_EXT_FEATURES:
3808 hci_remote_ext_features_evt(hdev, skb);
3809 break;
3810
3811 case HCI_EV_SYNC_CONN_COMPLETE:
3812 hci_sync_conn_complete_evt(hdev, skb);
3813 break;
3814
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003815 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3816 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003817 break;
3818
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003819 case HCI_EV_KEY_REFRESH_COMPLETE:
3820 hci_key_refresh_complete_evt(hdev, skb);
3821 break;
3822
Marcel Holtmann04936842008-07-14 20:13:48 +02003823 case HCI_EV_IO_CAPA_REQUEST:
3824 hci_io_capa_request_evt(hdev, skb);
3825 break;
3826
Johan Hedberg03b555e2011-01-04 15:40:05 +02003827 case HCI_EV_IO_CAPA_REPLY:
3828 hci_io_capa_reply_evt(hdev, skb);
3829 break;
3830
Johan Hedberga5c29682011-02-19 12:05:57 -03003831 case HCI_EV_USER_CONFIRM_REQUEST:
3832 hci_user_confirm_request_evt(hdev, skb);
3833 break;
3834
Brian Gix1143d452011-11-23 08:28:34 -08003835 case HCI_EV_USER_PASSKEY_REQUEST:
3836 hci_user_passkey_request_evt(hdev, skb);
3837 break;
3838
Johan Hedberg92a25252012-09-06 18:39:26 +03003839 case HCI_EV_USER_PASSKEY_NOTIFY:
3840 hci_user_passkey_notify_evt(hdev, skb);
3841 break;
3842
3843 case HCI_EV_KEYPRESS_NOTIFY:
3844 hci_keypress_notify_evt(hdev, skb);
3845 break;
3846
Marcel Holtmann04936842008-07-14 20:13:48 +02003847 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3848 hci_simple_pair_complete_evt(hdev, skb);
3849 break;
3850
Marcel Holtmann41a96212008-07-14 20:13:48 +02003851 case HCI_EV_REMOTE_HOST_FEATURES:
3852 hci_remote_host_features_evt(hdev, skb);
3853 break;
3854
Ville Tervofcd89c02011-02-10 22:38:47 -03003855 case HCI_EV_LE_META:
3856 hci_le_meta_evt(hdev, skb);
3857 break;
3858
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003859 case HCI_EV_CHANNEL_SELECTED:
3860 hci_chan_selected_evt(hdev, skb);
3861 break;
3862
Szymon Janc2763eda2011-03-22 13:12:22 +01003863 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3864 hci_remote_oob_data_request_evt(hdev, skb);
3865 break;
3866
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003867 case HCI_EV_PHY_LINK_COMPLETE:
3868 hci_phy_link_complete_evt(hdev, skb);
3869 break;
3870
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003871 case HCI_EV_LOGICAL_LINK_COMPLETE:
3872 hci_loglink_complete_evt(hdev, skb);
3873 break;
3874
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003875 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3876 hci_disconn_loglink_complete_evt(hdev, skb);
3877 break;
3878
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003879 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3880 hci_disconn_phylink_complete_evt(hdev, skb);
3881 break;
3882
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003883 case HCI_EV_NUM_COMP_BLOCKS:
3884 hci_num_comp_blocks_evt(hdev, skb);
3885 break;
3886
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003887 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003888 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003889 break;
3890 }
3891
3892 kfree_skb(skb);
3893 hdev->stat.evt_rx++;
3894}