blob: 0e71e6c47391d155434fb3c55bda4ea490315ae8 [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 Guedes07f7fa52011-12-02 21:13:31 +0900946}
947
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300948static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300949 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300950{
951 struct hci_cp_le_set_scan_enable *cp;
952 __u8 status = *((__u8 *) skb->data);
953
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300954 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300955
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300956 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
957 if (!cp)
958 return;
959
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200960 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -0300961 case LE_SCAN_ENABLE:
Andre Guedesfef52342013-04-30 15:29:29 -0300962 if (status)
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300963 return;
964
Andre Guedesd23264a2011-11-25 20:53:38 -0300965 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200966 break;
967
Andre Guedes76a388b2013-04-04 20:21:02 -0300968 case LE_SCAN_DISABLE:
Andre Guedesc9ecc482012-03-15 16:52:08 -0300969 if (status) {
970 hci_dev_lock(hdev);
971 mgmt_stop_discovery_failed(hdev, status);
972 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300973 return;
Andre Guedesc9ecc482012-03-15 16:52:08 -0300974 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300975
Andre Guedesd23264a2011-11-25 20:53:38 -0300976 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
977
Andre Guedesbc3dd332012-03-06 19:37:06 -0300978 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
979 hdev->discovery.state == DISCOVERY_FINDING) {
Andre Guedes5e0452c2012-02-17 20:39:38 -0300980 mgmt_interleaved_discovery(hdev);
981 } else {
982 hci_dev_lock(hdev);
983 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
984 hci_dev_unlock(hdev);
985 }
986
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200987 break;
988
989 default:
990 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
991 break;
Andre Guedes35815082011-05-26 16:23:53 -0300992 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300993}
994
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200995static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
996 struct sk_buff *skb)
997{
998 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
999
1000 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1001
1002 if (!rp->status)
1003 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001004}
1005
Johan Hedberg9b008c02013-01-22 14:02:01 +02001006static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1007 struct sk_buff *skb)
1008{
1009 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1010
1011 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1012
1013 if (!rp->status)
1014 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001015}
1016
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001017static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1018 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001019{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001020 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001021 __u8 status = *((__u8 *) skb->data);
1022
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001023 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001024
Johan Hedberg06199cf2012-02-22 16:37:11 +02001025 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001026 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001027 return;
1028
Johan Hedberg8f984df2012-02-28 01:07:22 +02001029 if (!status) {
1030 if (sent->le)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001031 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001032 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001033 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001034
1035 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001036 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001037 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001038 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001039 }
1040
1041 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001042 !test_bit(HCI_INIT, &hdev->flags))
Johan Hedberg8f984df2012-02-28 01:07:22 +02001043 mgmt_le_enable_complete(hdev, sent->le, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001044}
1045
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001046static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1047 struct sk_buff *skb)
1048{
1049 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1050
1051 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1052 hdev->name, rp->status, rp->phy_handle);
1053
1054 if (rp->status)
1055 return;
1056
1057 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1058}
1059
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001060static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001061{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001062 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001063
1064 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001065 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001066 return;
1067 }
1068
Andre Guedes89352e72011-11-04 14:16:53 -03001069 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001070}
1071
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001072static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001074 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001077 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001078
1079 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 if (!cp)
1081 return;
1082
1083 hci_dev_lock(hdev);
1084
1085 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1086
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001087 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
1089 if (status) {
1090 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001091 if (status != 0x0c || conn->attempt > 2) {
1092 conn->state = BT_CLOSED;
1093 hci_proto_connect_cfm(conn, status);
1094 hci_conn_del(conn);
1095 } else
1096 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 }
1098 } else {
1099 if (!conn) {
1100 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1101 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001102 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 conn->link_mode |= HCI_LM_MASTER;
1104 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001105 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106 }
1107 }
1108
1109 hci_dev_unlock(hdev);
1110}
1111
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001112static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001114 struct hci_cp_add_sco *cp;
1115 struct hci_conn *acl, *sco;
1116 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001118 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001119
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001120 if (!status)
1121 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001123 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1124 if (!cp)
1125 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001127 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001129 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001130
1131 hci_dev_lock(hdev);
1132
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001133 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001134 if (acl) {
1135 sco = acl->link;
1136 if (sco) {
1137 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001138
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001139 hci_proto_connect_cfm(sco, status);
1140 hci_conn_del(sco);
1141 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001142 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001143
1144 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145}
1146
Marcel Holtmannf8558552008-07-14 20:13:49 +02001147static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1148{
1149 struct hci_cp_auth_requested *cp;
1150 struct hci_conn *conn;
1151
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001152 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001153
1154 if (!status)
1155 return;
1156
1157 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1158 if (!cp)
1159 return;
1160
1161 hci_dev_lock(hdev);
1162
1163 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1164 if (conn) {
1165 if (conn->state == BT_CONFIG) {
1166 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001167 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001168 }
1169 }
1170
1171 hci_dev_unlock(hdev);
1172}
1173
1174static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1175{
1176 struct hci_cp_set_conn_encrypt *cp;
1177 struct hci_conn *conn;
1178
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001179 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001180
1181 if (!status)
1182 return;
1183
1184 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1185 if (!cp)
1186 return;
1187
1188 hci_dev_lock(hdev);
1189
1190 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1191 if (conn) {
1192 if (conn->state == BT_CONFIG) {
1193 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001194 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001195 }
1196 }
1197
1198 hci_dev_unlock(hdev);
1199}
1200
Johan Hedberg127178d2010-11-18 22:22:29 +02001201static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001202 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001203{
Johan Hedberg392599b2010-11-18 22:22:28 +02001204 if (conn->state != BT_CONFIG || !conn->out)
1205 return 0;
1206
Johan Hedberg765c2a92011-01-19 12:06:52 +05301207 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001208 return 0;
1209
1210 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001211 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001212 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1213 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001214 return 0;
1215
Johan Hedberg392599b2010-11-18 22:22:28 +02001216 return 1;
1217}
1218
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001219static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001220 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001221{
1222 struct hci_cp_remote_name_req cp;
1223
1224 memset(&cp, 0, sizeof(cp));
1225
1226 bacpy(&cp.bdaddr, &e->data.bdaddr);
1227 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1228 cp.pscan_mode = e->data.pscan_mode;
1229 cp.clock_offset = e->data.clock_offset;
1230
1231 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1232}
1233
Johan Hedbergb644ba32012-01-17 21:48:47 +02001234static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001235{
1236 struct discovery_state *discov = &hdev->discovery;
1237 struct inquiry_entry *e;
1238
Johan Hedbergb644ba32012-01-17 21:48:47 +02001239 if (list_empty(&discov->resolve))
1240 return false;
1241
1242 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001243 if (!e)
1244 return false;
1245
Johan Hedbergb644ba32012-01-17 21:48:47 +02001246 if (hci_resolve_name(hdev, e) == 0) {
1247 e->name_state = NAME_PENDING;
1248 return true;
1249 }
1250
1251 return false;
1252}
1253
1254static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001255 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001256{
1257 struct discovery_state *discov = &hdev->discovery;
1258 struct inquiry_entry *e;
1259
1260 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001261 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1262 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001263
1264 if (discov->state == DISCOVERY_STOPPED)
1265 return;
1266
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001267 if (discov->state == DISCOVERY_STOPPING)
1268 goto discov_complete;
1269
1270 if (discov->state != DISCOVERY_RESOLVING)
1271 return;
1272
1273 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001274 /* If the device was not found in a list of found devices names of which
1275 * are pending. there is no need to continue resolving a next name as it
1276 * will be done upon receiving another Remote Name Request Complete
1277 * Event */
1278 if (!e)
1279 return;
1280
1281 list_del(&e->list);
1282 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001283 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001284 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1285 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001286 } else {
1287 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001288 }
1289
Johan Hedbergb644ba32012-01-17 21:48:47 +02001290 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001291 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001292
1293discov_complete:
1294 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1295}
1296
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001297static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1298{
Johan Hedberg127178d2010-11-18 22:22:29 +02001299 struct hci_cp_remote_name_req *cp;
1300 struct hci_conn *conn;
1301
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001302 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001303
1304 /* If successful wait for the name req complete event before
1305 * checking for the need to do authentication */
1306 if (!status)
1307 return;
1308
1309 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1310 if (!cp)
1311 return;
1312
1313 hci_dev_lock(hdev);
1314
1315 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001316
1317 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1318 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1319
Johan Hedberg79c6c702011-04-28 11:28:55 -07001320 if (!conn)
1321 goto unlock;
1322
1323 if (!hci_outgoing_auth_needed(hdev, conn))
1324 goto unlock;
1325
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001326 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001327 struct hci_cp_auth_requested cp;
1328 cp.handle = __cpu_to_le16(conn->handle);
1329 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1330 }
1331
Johan Hedberg79c6c702011-04-28 11:28:55 -07001332unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001333 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001334}
1335
Marcel Holtmann769be972008-07-14 20:13:49 +02001336static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1337{
1338 struct hci_cp_read_remote_features *cp;
1339 struct hci_conn *conn;
1340
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001341 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001342
1343 if (!status)
1344 return;
1345
1346 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1347 if (!cp)
1348 return;
1349
1350 hci_dev_lock(hdev);
1351
1352 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1353 if (conn) {
1354 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001355 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001356 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001357 }
1358 }
1359
1360 hci_dev_unlock(hdev);
1361}
1362
1363static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1364{
1365 struct hci_cp_read_remote_ext_features *cp;
1366 struct hci_conn *conn;
1367
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001368 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001369
1370 if (!status)
1371 return;
1372
1373 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1374 if (!cp)
1375 return;
1376
1377 hci_dev_lock(hdev);
1378
1379 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1380 if (conn) {
1381 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001382 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001383 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001384 }
1385 }
1386
1387 hci_dev_unlock(hdev);
1388}
1389
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001390static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1391{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001392 struct hci_cp_setup_sync_conn *cp;
1393 struct hci_conn *acl, *sco;
1394 __u16 handle;
1395
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001396 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001397
1398 if (!status)
1399 return;
1400
1401 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1402 if (!cp)
1403 return;
1404
1405 handle = __le16_to_cpu(cp->handle);
1406
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001407 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001408
1409 hci_dev_lock(hdev);
1410
1411 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001412 if (acl) {
1413 sco = acl->link;
1414 if (sco) {
1415 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001416
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001417 hci_proto_connect_cfm(sco, status);
1418 hci_conn_del(sco);
1419 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001420 }
1421
1422 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001423}
1424
1425static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1426{
1427 struct hci_cp_sniff_mode *cp;
1428 struct hci_conn *conn;
1429
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001430 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001431
1432 if (!status)
1433 return;
1434
1435 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1436 if (!cp)
1437 return;
1438
1439 hci_dev_lock(hdev);
1440
1441 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001442 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001443 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001444
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001445 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001446 hci_sco_setup(conn, status);
1447 }
1448
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001449 hci_dev_unlock(hdev);
1450}
1451
1452static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1453{
1454 struct hci_cp_exit_sniff_mode *cp;
1455 struct hci_conn *conn;
1456
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001457 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001458
1459 if (!status)
1460 return;
1461
1462 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1463 if (!cp)
1464 return;
1465
1466 hci_dev_lock(hdev);
1467
1468 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001469 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001470 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001471
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001472 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001473 hci_sco_setup(conn, status);
1474 }
1475
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001476 hci_dev_unlock(hdev);
1477}
1478
Johan Hedberg88c3df12012-02-09 14:27:38 +02001479static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1480{
1481 struct hci_cp_disconnect *cp;
1482 struct hci_conn *conn;
1483
1484 if (!status)
1485 return;
1486
1487 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1488 if (!cp)
1489 return;
1490
1491 hci_dev_lock(hdev);
1492
1493 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1494 if (conn)
1495 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001496 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001497
1498 hci_dev_unlock(hdev);
1499}
1500
Ville Tervofcd89c02011-02-10 22:38:47 -03001501static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1502{
Ville Tervofcd89c02011-02-10 22:38:47 -03001503 struct hci_conn *conn;
1504
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001505 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Ville Tervofcd89c02011-02-10 22:38:47 -03001506
Ville Tervofcd89c02011-02-10 22:38:47 -03001507 if (status) {
Andre Guedesf00a06a2012-07-27 15:10:13 -03001508 hci_dev_lock(hdev);
Ville Tervofcd89c02011-02-10 22:38:47 -03001509
Andre Guedes0c95ab72012-07-27 15:10:14 -03001510 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001511 if (!conn) {
1512 hci_dev_unlock(hdev);
1513 return;
1514 }
1515
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001516 BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001517
1518 conn->state = BT_CLOSED;
Andre Guedes0c95ab72012-07-27 15:10:14 -03001519 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Andre Guedesf00a06a2012-07-27 15:10:13 -03001520 conn->dst_type, status);
1521 hci_proto_connect_cfm(conn, status);
1522 hci_conn_del(conn);
1523
1524 hci_dev_unlock(hdev);
1525 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001526}
1527
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001528static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1529{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001530 struct hci_cp_create_phy_link *cp;
1531
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001532 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001533
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001534 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1535 if (!cp)
1536 return;
1537
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001538 hci_dev_lock(hdev);
1539
1540 if (status) {
1541 struct hci_conn *hcon;
1542
1543 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1544 if (hcon)
1545 hci_conn_del(hcon);
1546 } else {
1547 amp_write_remote_assoc(hdev, cp->phy_handle);
1548 }
1549
1550 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001551}
1552
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001553static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1554{
1555 struct hci_cp_accept_phy_link *cp;
1556
1557 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1558
1559 if (status)
1560 return;
1561
1562 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1563 if (!cp)
1564 return;
1565
1566 amp_write_remote_assoc(hdev, cp->phy_handle);
1567}
1568
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001569static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001570{
1571 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001572 struct discovery_state *discov = &hdev->discovery;
1573 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001574
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001575 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001576
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001577 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001578
1579 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1580 return;
1581
Andre Guedes3e13fa12013-03-27 20:04:56 -03001582 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1583 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1584
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001585 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001586 return;
1587
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001588 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001589
Andre Guedes343f9352012-02-17 20:39:37 -03001590 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001591 goto unlock;
1592
1593 if (list_empty(&discov->resolve)) {
1594 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1595 goto unlock;
1596 }
1597
1598 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1599 if (e && hci_resolve_name(hdev, e) == 0) {
1600 e->name_state = NAME_PENDING;
1601 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1602 } else {
1603 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1604 }
1605
1606unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001607 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001608}
1609
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001610static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001612 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001613 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 int num_rsp = *((__u8 *) skb->data);
1615
1616 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1617
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001618 if (!num_rsp)
1619 return;
1620
Andre Guedes1519cc12012-03-21 00:03:38 -03001621 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1622 return;
1623
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001625
Johan Hedberge17acd42011-03-30 23:57:16 +03001626 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001627 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001628
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 bacpy(&data.bdaddr, &info->bdaddr);
1630 data.pscan_rep_mode = info->pscan_rep_mode;
1631 data.pscan_period_mode = info->pscan_period_mode;
1632 data.pscan_mode = info->pscan_mode;
1633 memcpy(data.dev_class, info->dev_class, 3);
1634 data.clock_offset = info->clock_offset;
1635 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001636 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001637
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001638 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001639 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001640 info->dev_class, 0, !name_known, ssp, NULL,
1641 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001643
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 hci_dev_unlock(hdev);
1645}
1646
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001647static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001649 struct hci_ev_conn_complete *ev = (void *) skb->data;
1650 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001652 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001653
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001655
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001656 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001657 if (!conn) {
1658 if (ev->link_type != SCO_LINK)
1659 goto unlock;
1660
1661 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1662 if (!conn)
1663 goto unlock;
1664
1665 conn->type = SCO_LINK;
1666 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001667
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001668 if (!ev->status) {
1669 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001670
1671 if (conn->type == ACL_LINK) {
1672 conn->state = BT_CONFIG;
1673 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001674
1675 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1676 !hci_find_link_key(hdev, &ev->bdaddr))
1677 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1678 else
1679 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001680 } else
1681 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001682
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001683 hci_conn_add_sysfs(conn);
1684
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001685 if (test_bit(HCI_AUTH, &hdev->flags))
1686 conn->link_mode |= HCI_LM_AUTH;
1687
1688 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1689 conn->link_mode |= HCI_LM_ENCRYPT;
1690
1691 /* Get remote features */
1692 if (conn->type == ACL_LINK) {
1693 struct hci_cp_read_remote_features cp;
1694 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001695 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001696 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001697 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001698
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001699 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001700 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001701 struct hci_cp_change_conn_ptype cp;
1702 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001703 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001704 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1705 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001706 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001707 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001708 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001709 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001710 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001711 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001712 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001713
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001714 if (conn->type == ACL_LINK)
1715 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001716
Marcel Holtmann769be972008-07-14 20:13:49 +02001717 if (ev->status) {
1718 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001719 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001720 } else if (ev->link_type != ACL_LINK)
1721 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001722
1723unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001725
1726 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727}
1728
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001729static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001731 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001733 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001735 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001736 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001738 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1739 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
Szymon Janc138d22e2011-02-17 16:44:23 +01001741 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001742 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001744 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746
1747 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001748
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001749 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1750 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001751 memcpy(ie->data.dev_class, ev->dev_class, 3);
1752
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001753 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1754 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001756 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1757 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001758 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759 hci_dev_unlock(hdev);
1760 return;
1761 }
1762 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001763
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001765
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 hci_dev_unlock(hdev);
1767
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001768 if (ev->link_type == ACL_LINK ||
1769 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001770 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001771 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001773 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001775 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1776 cp.role = 0x00; /* Become master */
1777 else
1778 cp.role = 0x01; /* Remain slave */
1779
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001780 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1781 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001782 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001783 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001784 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001785
1786 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001787 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001788
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001789 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1790 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1791 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001792 cp.content_format = cpu_to_le16(hdev->voice_setting);
1793 cp.retrans_effort = 0xff;
1794
1795 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001796 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001797 } else {
1798 conn->state = BT_CONNECT2;
1799 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001800 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 } else {
1802 /* Connection rejected */
1803 struct hci_cp_reject_conn_req cp;
1804
1805 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001806 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001807 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 }
1809}
1810
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001811static u8 hci_to_mgmt_reason(u8 err)
1812{
1813 switch (err) {
1814 case HCI_ERROR_CONNECTION_TIMEOUT:
1815 return MGMT_DEV_DISCONN_TIMEOUT;
1816 case HCI_ERROR_REMOTE_USER_TERM:
1817 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1818 case HCI_ERROR_REMOTE_POWER_OFF:
1819 return MGMT_DEV_DISCONN_REMOTE;
1820 case HCI_ERROR_LOCAL_HOST_TERM:
1821 return MGMT_DEV_DISCONN_LOCAL_HOST;
1822 default:
1823 return MGMT_DEV_DISCONN_UNKNOWN;
1824 }
1825}
1826
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001827static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001829 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001830 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001832 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 hci_dev_lock(hdev);
1835
Marcel Holtmann04837f62006-07-03 10:02:33 +02001836 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001837 if (!conn)
1838 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001839
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001840 if (ev->status == 0)
1841 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842
Johan Hedbergb644ba32012-01-17 21:48:47 +02001843 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001844 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001845 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001846 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001847 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001848 } else {
1849 u8 reason = hci_to_mgmt_reason(ev->reason);
1850
Johan Hedbergafc747a2012-01-15 18:11:07 +02001851 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001852 conn->dst_type, reason);
1853 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001854 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001855
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001856 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301857 if (conn->type == ACL_LINK && conn->flush_key)
1858 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001859 hci_proto_disconn_cfm(conn, ev->reason);
1860 hci_conn_del(conn);
1861 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001862
1863unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864 hci_dev_unlock(hdev);
1865}
1866
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001867static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001868{
1869 struct hci_ev_auth_complete *ev = (void *) skb->data;
1870 struct hci_conn *conn;
1871
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001872 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001873
1874 hci_dev_lock(hdev);
1875
1876 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001877 if (!conn)
1878 goto unlock;
1879
1880 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001881 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001882 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001883 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001884 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001885 conn->link_mode |= HCI_LM_AUTH;
1886 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001887 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001888 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001889 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001890 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001891 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001892
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001893 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1894 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001895
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001896 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001897 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001898 struct hci_cp_set_conn_encrypt cp;
1899 cp.handle = ev->handle;
1900 cp.encrypt = 0x01;
1901 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001902 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001903 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001904 conn->state = BT_CONNECTED;
1905 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001906 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001907 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001908 } else {
1909 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001910
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001911 hci_conn_hold(conn);
1912 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001913 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001914 }
1915
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001916 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001917 if (!ev->status) {
1918 struct hci_cp_set_conn_encrypt cp;
1919 cp.handle = ev->handle;
1920 cp.encrypt = 0x01;
1921 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001922 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001923 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001924 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001925 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001926 }
1927 }
1928
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001929unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001930 hci_dev_unlock(hdev);
1931}
1932
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001933static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001934{
Johan Hedberg127178d2010-11-18 22:22:29 +02001935 struct hci_ev_remote_name *ev = (void *) skb->data;
1936 struct hci_conn *conn;
1937
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001938 BT_DBG("%s", hdev->name);
1939
1940 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001941
1942 hci_dev_lock(hdev);
1943
1944 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001945
1946 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1947 goto check_auth;
1948
1949 if (ev->status == 0)
1950 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001951 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001952 else
1953 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1954
1955check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001956 if (!conn)
1957 goto unlock;
1958
1959 if (!hci_outgoing_auth_needed(hdev, conn))
1960 goto unlock;
1961
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001962 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001963 struct hci_cp_auth_requested cp;
1964 cp.handle = __cpu_to_le16(conn->handle);
1965 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1966 }
1967
Johan Hedberg79c6c702011-04-28 11:28:55 -07001968unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001969 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001970}
1971
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001972static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001973{
1974 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1975 struct hci_conn *conn;
1976
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001977 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001978
1979 hci_dev_lock(hdev);
1980
1981 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1982 if (conn) {
1983 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001984 if (ev->encrypt) {
1985 /* Encryption implies authentication */
1986 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001987 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001988 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001989 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001990 conn->link_mode &= ~HCI_LM_ENCRYPT;
1991 }
1992
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001993 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001994
Gustavo Padovana7d77232012-05-13 03:20:07 -03001995 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03001996 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02001997 hci_conn_drop(conn);
Gustavo Padovana7d77232012-05-13 03:20:07 -03001998 goto unlock;
1999 }
2000
Marcel Holtmannf8558552008-07-14 20:13:49 +02002001 if (conn->state == BT_CONFIG) {
2002 if (!ev->status)
2003 conn->state = BT_CONNECTED;
2004
2005 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002006 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02002007 } else
2008 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002009 }
2010
Gustavo Padovana7d77232012-05-13 03:20:07 -03002011unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002012 hci_dev_unlock(hdev);
2013}
2014
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002015static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2016 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002017{
2018 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2019 struct hci_conn *conn;
2020
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002021 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002022
2023 hci_dev_lock(hdev);
2024
2025 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2026 if (conn) {
2027 if (!ev->status)
2028 conn->link_mode |= HCI_LM_SECURE;
2029
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002030 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002031
2032 hci_key_change_cfm(conn, ev->status);
2033 }
2034
2035 hci_dev_unlock(hdev);
2036}
2037
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002038static void hci_remote_features_evt(struct hci_dev *hdev,
2039 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002040{
2041 struct hci_ev_remote_features *ev = (void *) skb->data;
2042 struct hci_conn *conn;
2043
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002044 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002045
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002046 hci_dev_lock(hdev);
2047
2048 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002049 if (!conn)
2050 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002051
Johan Hedbergccd556f2010-11-10 17:11:51 +02002052 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002053 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002054
2055 if (conn->state != BT_CONFIG)
2056 goto unlock;
2057
2058 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2059 struct hci_cp_read_remote_ext_features cp;
2060 cp.handle = ev->handle;
2061 cp.page = 0x01;
2062 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002063 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002064 goto unlock;
2065 }
2066
Johan Hedberg671267b2012-05-12 16:11:50 -03002067 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002068 struct hci_cp_remote_name_req cp;
2069 memset(&cp, 0, sizeof(cp));
2070 bacpy(&cp.bdaddr, &conn->dst);
2071 cp.pscan_rep_mode = 0x02;
2072 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002073 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2074 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002075 conn->dst_type, 0, NULL, 0,
2076 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002077
Johan Hedberg127178d2010-11-18 22:22:29 +02002078 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002079 conn->state = BT_CONNECTED;
2080 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002081 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002082 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002083
Johan Hedbergccd556f2010-11-10 17:11:51 +02002084unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002085 hci_dev_unlock(hdev);
2086}
2087
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002088static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002089{
2090 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002091 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002092 __u16 opcode;
2093
2094 skb_pull(skb, sizeof(*ev));
2095
2096 opcode = __le16_to_cpu(ev->opcode);
2097
2098 switch (opcode) {
2099 case HCI_OP_INQUIRY_CANCEL:
2100 hci_cc_inquiry_cancel(hdev, skb);
2101 break;
2102
Andre Guedes4d934832012-03-21 00:03:35 -03002103 case HCI_OP_PERIODIC_INQ:
2104 hci_cc_periodic_inq(hdev, skb);
2105 break;
2106
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002107 case HCI_OP_EXIT_PERIODIC_INQ:
2108 hci_cc_exit_periodic_inq(hdev, skb);
2109 break;
2110
2111 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2112 hci_cc_remote_name_req_cancel(hdev, skb);
2113 break;
2114
2115 case HCI_OP_ROLE_DISCOVERY:
2116 hci_cc_role_discovery(hdev, skb);
2117 break;
2118
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002119 case HCI_OP_READ_LINK_POLICY:
2120 hci_cc_read_link_policy(hdev, skb);
2121 break;
2122
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002123 case HCI_OP_WRITE_LINK_POLICY:
2124 hci_cc_write_link_policy(hdev, skb);
2125 break;
2126
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002127 case HCI_OP_READ_DEF_LINK_POLICY:
2128 hci_cc_read_def_link_policy(hdev, skb);
2129 break;
2130
2131 case HCI_OP_WRITE_DEF_LINK_POLICY:
2132 hci_cc_write_def_link_policy(hdev, skb);
2133 break;
2134
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002135 case HCI_OP_RESET:
2136 hci_cc_reset(hdev, skb);
2137 break;
2138
2139 case HCI_OP_WRITE_LOCAL_NAME:
2140 hci_cc_write_local_name(hdev, skb);
2141 break;
2142
2143 case HCI_OP_READ_LOCAL_NAME:
2144 hci_cc_read_local_name(hdev, skb);
2145 break;
2146
2147 case HCI_OP_WRITE_AUTH_ENABLE:
2148 hci_cc_write_auth_enable(hdev, skb);
2149 break;
2150
2151 case HCI_OP_WRITE_ENCRYPT_MODE:
2152 hci_cc_write_encrypt_mode(hdev, skb);
2153 break;
2154
2155 case HCI_OP_WRITE_SCAN_ENABLE:
2156 hci_cc_write_scan_enable(hdev, skb);
2157 break;
2158
2159 case HCI_OP_READ_CLASS_OF_DEV:
2160 hci_cc_read_class_of_dev(hdev, skb);
2161 break;
2162
2163 case HCI_OP_WRITE_CLASS_OF_DEV:
2164 hci_cc_write_class_of_dev(hdev, skb);
2165 break;
2166
2167 case HCI_OP_READ_VOICE_SETTING:
2168 hci_cc_read_voice_setting(hdev, skb);
2169 break;
2170
2171 case HCI_OP_WRITE_VOICE_SETTING:
2172 hci_cc_write_voice_setting(hdev, skb);
2173 break;
2174
Marcel Holtmann333140b2008-07-14 20:13:48 +02002175 case HCI_OP_WRITE_SSP_MODE:
2176 hci_cc_write_ssp_mode(hdev, skb);
2177 break;
2178
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002179 case HCI_OP_READ_LOCAL_VERSION:
2180 hci_cc_read_local_version(hdev, skb);
2181 break;
2182
2183 case HCI_OP_READ_LOCAL_COMMANDS:
2184 hci_cc_read_local_commands(hdev, skb);
2185 break;
2186
2187 case HCI_OP_READ_LOCAL_FEATURES:
2188 hci_cc_read_local_features(hdev, skb);
2189 break;
2190
Andre Guedes971e3a42011-06-30 19:20:52 -03002191 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2192 hci_cc_read_local_ext_features(hdev, skb);
2193 break;
2194
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002195 case HCI_OP_READ_BUFFER_SIZE:
2196 hci_cc_read_buffer_size(hdev, skb);
2197 break;
2198
2199 case HCI_OP_READ_BD_ADDR:
2200 hci_cc_read_bd_addr(hdev, skb);
2201 break;
2202
Johan Hedbergf332ec62013-03-15 17:07:11 -05002203 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2204 hci_cc_read_page_scan_activity(hdev, skb);
2205 break;
2206
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002207 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2208 hci_cc_write_page_scan_activity(hdev, skb);
2209 break;
2210
Johan Hedbergf332ec62013-03-15 17:07:11 -05002211 case HCI_OP_READ_PAGE_SCAN_TYPE:
2212 hci_cc_read_page_scan_type(hdev, skb);
2213 break;
2214
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002215 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2216 hci_cc_write_page_scan_type(hdev, skb);
2217 break;
2218
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002219 case HCI_OP_READ_DATA_BLOCK_SIZE:
2220 hci_cc_read_data_block_size(hdev, skb);
2221 break;
2222
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002223 case HCI_OP_READ_FLOW_CONTROL_MODE:
2224 hci_cc_read_flow_control_mode(hdev, skb);
2225 break;
2226
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002227 case HCI_OP_READ_LOCAL_AMP_INFO:
2228 hci_cc_read_local_amp_info(hdev, skb);
2229 break;
2230
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002231 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2232 hci_cc_read_local_amp_assoc(hdev, skb);
2233 break;
2234
Johan Hedbergd5859e22011-01-25 01:19:58 +02002235 case HCI_OP_READ_INQ_RSP_TX_POWER:
2236 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2237 break;
2238
Johan Hedberg980e1a52011-01-22 06:10:07 +02002239 case HCI_OP_PIN_CODE_REPLY:
2240 hci_cc_pin_code_reply(hdev, skb);
2241 break;
2242
2243 case HCI_OP_PIN_CODE_NEG_REPLY:
2244 hci_cc_pin_code_neg_reply(hdev, skb);
2245 break;
2246
Szymon Jancc35938b2011-03-22 13:12:21 +01002247 case HCI_OP_READ_LOCAL_OOB_DATA:
2248 hci_cc_read_local_oob_data_reply(hdev, skb);
2249 break;
2250
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002251 case HCI_OP_LE_READ_BUFFER_SIZE:
2252 hci_cc_le_read_buffer_size(hdev, skb);
2253 break;
2254
Johan Hedberg60e77322013-01-22 14:01:59 +02002255 case HCI_OP_LE_READ_LOCAL_FEATURES:
2256 hci_cc_le_read_local_features(hdev, skb);
2257 break;
2258
Johan Hedberg8fa19092012-10-19 20:57:49 +03002259 case HCI_OP_LE_READ_ADV_TX_POWER:
2260 hci_cc_le_read_adv_tx_power(hdev, skb);
2261 break;
2262
Johan Hedberga5c29682011-02-19 12:05:57 -03002263 case HCI_OP_USER_CONFIRM_REPLY:
2264 hci_cc_user_confirm_reply(hdev, skb);
2265 break;
2266
2267 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2268 hci_cc_user_confirm_neg_reply(hdev, skb);
2269 break;
2270
Brian Gix1143d452011-11-23 08:28:34 -08002271 case HCI_OP_USER_PASSKEY_REPLY:
2272 hci_cc_user_passkey_reply(hdev, skb);
2273 break;
2274
2275 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2276 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002277 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002278
2279 case HCI_OP_LE_SET_SCAN_PARAM:
2280 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002281 break;
2282
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002283 case HCI_OP_LE_SET_ADV_ENABLE:
2284 hci_cc_le_set_adv_enable(hdev, skb);
2285 break;
2286
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002287 case HCI_OP_LE_SET_SCAN_ENABLE:
2288 hci_cc_le_set_scan_enable(hdev, skb);
2289 break;
2290
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002291 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2292 hci_cc_le_read_white_list_size(hdev, skb);
2293 break;
2294
Johan Hedberg9b008c02013-01-22 14:02:01 +02002295 case HCI_OP_LE_READ_SUPPORTED_STATES:
2296 hci_cc_le_read_supported_states(hdev, skb);
2297 break;
2298
Andre Guedesf9b49302011-06-30 19:20:53 -03002299 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2300 hci_cc_write_le_host_supported(hdev, skb);
2301 break;
2302
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002303 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2304 hci_cc_write_remote_amp_assoc(hdev, skb);
2305 break;
2306
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002307 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002308 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002309 break;
2310 }
2311
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002312 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002313 del_timer(&hdev->cmd_timer);
2314
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002315 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002316
Szymon Jancdbccd792012-12-11 08:51:19 +01002317 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002318 atomic_set(&hdev->cmd_cnt, 1);
2319 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002320 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002321 }
2322}
2323
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002324static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002325{
2326 struct hci_ev_cmd_status *ev = (void *) skb->data;
2327 __u16 opcode;
2328
2329 skb_pull(skb, sizeof(*ev));
2330
2331 opcode = __le16_to_cpu(ev->opcode);
2332
2333 switch (opcode) {
2334 case HCI_OP_INQUIRY:
2335 hci_cs_inquiry(hdev, ev->status);
2336 break;
2337
2338 case HCI_OP_CREATE_CONN:
2339 hci_cs_create_conn(hdev, ev->status);
2340 break;
2341
2342 case HCI_OP_ADD_SCO:
2343 hci_cs_add_sco(hdev, ev->status);
2344 break;
2345
Marcel Holtmannf8558552008-07-14 20:13:49 +02002346 case HCI_OP_AUTH_REQUESTED:
2347 hci_cs_auth_requested(hdev, ev->status);
2348 break;
2349
2350 case HCI_OP_SET_CONN_ENCRYPT:
2351 hci_cs_set_conn_encrypt(hdev, ev->status);
2352 break;
2353
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002354 case HCI_OP_REMOTE_NAME_REQ:
2355 hci_cs_remote_name_req(hdev, ev->status);
2356 break;
2357
Marcel Holtmann769be972008-07-14 20:13:49 +02002358 case HCI_OP_READ_REMOTE_FEATURES:
2359 hci_cs_read_remote_features(hdev, ev->status);
2360 break;
2361
2362 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2363 hci_cs_read_remote_ext_features(hdev, ev->status);
2364 break;
2365
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002366 case HCI_OP_SETUP_SYNC_CONN:
2367 hci_cs_setup_sync_conn(hdev, ev->status);
2368 break;
2369
2370 case HCI_OP_SNIFF_MODE:
2371 hci_cs_sniff_mode(hdev, ev->status);
2372 break;
2373
2374 case HCI_OP_EXIT_SNIFF_MODE:
2375 hci_cs_exit_sniff_mode(hdev, ev->status);
2376 break;
2377
Johan Hedberg8962ee72011-01-20 12:40:27 +02002378 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002379 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002380 break;
2381
Ville Tervofcd89c02011-02-10 22:38:47 -03002382 case HCI_OP_LE_CREATE_CONN:
2383 hci_cs_le_create_conn(hdev, ev->status);
2384 break;
2385
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002386 case HCI_OP_CREATE_PHY_LINK:
2387 hci_cs_create_phylink(hdev, ev->status);
2388 break;
2389
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002390 case HCI_OP_ACCEPT_PHY_LINK:
2391 hci_cs_accept_phylink(hdev, ev->status);
2392 break;
2393
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002394 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002395 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002396 break;
2397 }
2398
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002399 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002400 del_timer(&hdev->cmd_timer);
2401
Johan Hedberg02350a72013-04-03 21:50:29 +03002402 if (ev->status ||
2403 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2404 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002405
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002406 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002407 atomic_set(&hdev->cmd_cnt, 1);
2408 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002409 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002410 }
2411}
2412
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002413static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002414{
2415 struct hci_ev_role_change *ev = (void *) skb->data;
2416 struct hci_conn *conn;
2417
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002418 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002419
2420 hci_dev_lock(hdev);
2421
2422 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2423 if (conn) {
2424 if (!ev->status) {
2425 if (ev->role)
2426 conn->link_mode &= ~HCI_LM_MASTER;
2427 else
2428 conn->link_mode |= HCI_LM_MASTER;
2429 }
2430
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002431 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002432
2433 hci_role_switch_cfm(conn, ev->status, ev->role);
2434 }
2435
2436 hci_dev_unlock(hdev);
2437}
2438
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002439static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002441 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442 int i;
2443
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002444 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2445 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2446 return;
2447 }
2448
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002449 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002450 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451 BT_DBG("%s bad parameters", hdev->name);
2452 return;
2453 }
2454
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002455 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2456
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002457 for (i = 0; i < ev->num_hndl; i++) {
2458 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002459 struct hci_conn *conn;
2460 __u16 handle, count;
2461
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002462 handle = __le16_to_cpu(info->handle);
2463 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002464
2465 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002466 if (!conn)
2467 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002468
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002469 conn->sent -= count;
2470
2471 switch (conn->type) {
2472 case ACL_LINK:
2473 hdev->acl_cnt += count;
2474 if (hdev->acl_cnt > hdev->acl_pkts)
2475 hdev->acl_cnt = hdev->acl_pkts;
2476 break;
2477
2478 case LE_LINK:
2479 if (hdev->le_pkts) {
2480 hdev->le_cnt += count;
2481 if (hdev->le_cnt > hdev->le_pkts)
2482 hdev->le_cnt = hdev->le_pkts;
2483 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002484 hdev->acl_cnt += count;
2485 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486 hdev->acl_cnt = hdev->acl_pkts;
2487 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002488 break;
2489
2490 case SCO_LINK:
2491 hdev->sco_cnt += count;
2492 if (hdev->sco_cnt > hdev->sco_pkts)
2493 hdev->sco_cnt = hdev->sco_pkts;
2494 break;
2495
2496 default:
2497 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2498 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 }
2500 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002501
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002502 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503}
2504
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002505static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2506 __u16 handle)
2507{
2508 struct hci_chan *chan;
2509
2510 switch (hdev->dev_type) {
2511 case HCI_BREDR:
2512 return hci_conn_hash_lookup_handle(hdev, handle);
2513 case HCI_AMP:
2514 chan = hci_chan_lookup_handle(hdev, handle);
2515 if (chan)
2516 return chan->conn;
2517 break;
2518 default:
2519 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2520 break;
2521 }
2522
2523 return NULL;
2524}
2525
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002526static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002527{
2528 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2529 int i;
2530
2531 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2532 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2533 return;
2534 }
2535
2536 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002537 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002538 BT_DBG("%s bad parameters", hdev->name);
2539 return;
2540 }
2541
2542 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002543 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002544
2545 for (i = 0; i < ev->num_hndl; i++) {
2546 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002547 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002548 __u16 handle, block_count;
2549
2550 handle = __le16_to_cpu(info->handle);
2551 block_count = __le16_to_cpu(info->blocks);
2552
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002553 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002554 if (!conn)
2555 continue;
2556
2557 conn->sent -= block_count;
2558
2559 switch (conn->type) {
2560 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002561 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002562 hdev->block_cnt += block_count;
2563 if (hdev->block_cnt > hdev->num_blocks)
2564 hdev->block_cnt = hdev->num_blocks;
2565 break;
2566
2567 default:
2568 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2569 break;
2570 }
2571 }
2572
2573 queue_work(hdev->workqueue, &hdev->tx_work);
2574}
2575
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002576static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002578 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002579 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002581 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582
2583 hci_dev_lock(hdev);
2584
Marcel Holtmann04837f62006-07-03 10:02:33 +02002585 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2586 if (conn) {
2587 conn->mode = ev->mode;
2588 conn->interval = __le16_to_cpu(ev->interval);
2589
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002590 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2591 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002592 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002593 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002594 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002595 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002596 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002597
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002598 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002599 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002600 }
2601
2602 hci_dev_unlock(hdev);
2603}
2604
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002605static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002607 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2608 struct hci_conn *conn;
2609
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002610 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002611
2612 hci_dev_lock(hdev);
2613
2614 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002615 if (!conn)
2616 goto unlock;
2617
2618 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002619 hci_conn_hold(conn);
2620 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002621 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002622 }
2623
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002624 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002625 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002626 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002627 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002628 u8 secure;
2629
2630 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2631 secure = 1;
2632 else
2633 secure = 0;
2634
Johan Hedberg744cf192011-11-08 20:40:14 +02002635 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002636 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002637
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002638unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002639 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640}
2641
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002642static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002643{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002644 struct hci_ev_link_key_req *ev = (void *) skb->data;
2645 struct hci_cp_link_key_reply cp;
2646 struct hci_conn *conn;
2647 struct link_key *key;
2648
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002649 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002650
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002651 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002652 return;
2653
2654 hci_dev_lock(hdev);
2655
2656 key = hci_find_link_key(hdev, &ev->bdaddr);
2657 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002658 BT_DBG("%s link key not found for %pMR", hdev->name,
2659 &ev->bdaddr);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002660 goto not_found;
2661 }
2662
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002663 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2664 &ev->bdaddr);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002665
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002666 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002667 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002668 BT_DBG("%s ignoring debug key", hdev->name);
2669 goto not_found;
2670 }
2671
2672 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002673 if (conn) {
2674 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002675 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002676 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2677 goto not_found;
2678 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002679
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002680 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002681 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002682 BT_DBG("%s ignoring key unauthenticated for high security",
2683 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002684 goto not_found;
2685 }
2686
2687 conn->key_type = key->type;
2688 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002689 }
2690
2691 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002692 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002693
2694 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2695
2696 hci_dev_unlock(hdev);
2697
2698 return;
2699
2700not_found:
2701 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2702 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002703}
2704
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002705static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002707 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2708 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002709 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002710
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002711 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002712
2713 hci_dev_lock(hdev);
2714
2715 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2716 if (conn) {
2717 hci_conn_hold(conn);
2718 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002719 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002720
2721 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2722 conn->key_type = ev->key_type;
2723
David Herrmann76a68ba2013-04-06 20:28:37 +02002724 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002725 }
2726
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002727 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002728 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002729 ev->key_type, pin_len);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002730
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002731 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002732}
2733
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002734static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002735{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002736 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002737 struct hci_conn *conn;
2738
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002739 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002740
2741 hci_dev_lock(hdev);
2742
2743 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744 if (conn && !ev->status) {
2745 struct inquiry_entry *ie;
2746
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002747 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2748 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749 ie->data.clock_offset = ev->clock_offset;
2750 ie->timestamp = jiffies;
2751 }
2752 }
2753
2754 hci_dev_unlock(hdev);
2755}
2756
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002757static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002758{
2759 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2760 struct hci_conn *conn;
2761
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002762 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002763
2764 hci_dev_lock(hdev);
2765
2766 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2767 if (conn && !ev->status)
2768 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2769
2770 hci_dev_unlock(hdev);
2771}
2772
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002773static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002774{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002775 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002776 struct inquiry_entry *ie;
2777
2778 BT_DBG("%s", hdev->name);
2779
2780 hci_dev_lock(hdev);
2781
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002782 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2783 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002784 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2785 ie->timestamp = jiffies;
2786 }
2787
2788 hci_dev_unlock(hdev);
2789}
2790
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002791static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2792 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002793{
2794 struct inquiry_data data;
2795 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002796 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002797
2798 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2799
2800 if (!num_rsp)
2801 return;
2802
Andre Guedes1519cc12012-03-21 00:03:38 -03002803 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2804 return;
2805
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002806 hci_dev_lock(hdev);
2807
2808 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002809 struct inquiry_info_with_rssi_and_pscan_mode *info;
2810 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002811
Johan Hedberge17acd42011-03-30 23:57:16 +03002812 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002813 bacpy(&data.bdaddr, &info->bdaddr);
2814 data.pscan_rep_mode = info->pscan_rep_mode;
2815 data.pscan_period_mode = info->pscan_period_mode;
2816 data.pscan_mode = info->pscan_mode;
2817 memcpy(data.dev_class, info->dev_class, 3);
2818 data.clock_offset = info->clock_offset;
2819 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002820 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002821
2822 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002823 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002824 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002825 info->dev_class, info->rssi,
2826 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002827 }
2828 } else {
2829 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2830
Johan Hedberge17acd42011-03-30 23:57:16 +03002831 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002832 bacpy(&data.bdaddr, &info->bdaddr);
2833 data.pscan_rep_mode = info->pscan_rep_mode;
2834 data.pscan_period_mode = info->pscan_period_mode;
2835 data.pscan_mode = 0x00;
2836 memcpy(data.dev_class, info->dev_class, 3);
2837 data.clock_offset = info->clock_offset;
2838 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002839 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002840 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002841 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002842 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002843 info->dev_class, info->rssi,
2844 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002845 }
2846 }
2847
2848 hci_dev_unlock(hdev);
2849}
2850
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002851static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2852 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002853{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002854 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2855 struct hci_conn *conn;
2856
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002857 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002858
Marcel Holtmann41a96212008-07-14 20:13:48 +02002859 hci_dev_lock(hdev);
2860
2861 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002862 if (!conn)
2863 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002864
Johan Hedbergcad718e2013-04-17 15:00:51 +03002865 if (ev->page < HCI_MAX_PAGES)
2866 memcpy(conn->features[ev->page], ev->features, 8);
2867
Johan Hedbergccd556f2010-11-10 17:11:51 +02002868 if (!ev->status && ev->page == 0x01) {
2869 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002870
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002871 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2872 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002873 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002874
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302875 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002876 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302877 } else {
2878 /* It is mandatory by the Bluetooth specification that
2879 * Extended Inquiry Results are only used when Secure
2880 * Simple Pairing is enabled, but some devices violate
2881 * this.
2882 *
2883 * To make these devices work, the internal SSP
2884 * enabled flag needs to be cleared if the remote host
2885 * features do not indicate SSP support */
2886 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2887 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002888 }
2889
Johan Hedbergccd556f2010-11-10 17:11:51 +02002890 if (conn->state != BT_CONFIG)
2891 goto unlock;
2892
Johan Hedberg671267b2012-05-12 16:11:50 -03002893 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002894 struct hci_cp_remote_name_req cp;
2895 memset(&cp, 0, sizeof(cp));
2896 bacpy(&cp.bdaddr, &conn->dst);
2897 cp.pscan_rep_mode = 0x02;
2898 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002899 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2900 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002901 conn->dst_type, 0, NULL, 0,
2902 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002903
Johan Hedberg127178d2010-11-18 22:22:29 +02002904 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002905 conn->state = BT_CONNECTED;
2906 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002907 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002908 }
2909
2910unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002911 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002912}
2913
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002914static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2915 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002916{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002917 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2918 struct hci_conn *conn;
2919
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002920 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002921
2922 hci_dev_lock(hdev);
2923
2924 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002925 if (!conn) {
2926 if (ev->link_type == ESCO_LINK)
2927 goto unlock;
2928
2929 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2930 if (!conn)
2931 goto unlock;
2932
2933 conn->type = SCO_LINK;
2934 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002935
Marcel Holtmann732547f2009-04-19 19:14:14 +02002936 switch (ev->status) {
2937 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002938 conn->handle = __le16_to_cpu(ev->handle);
2939 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002940
2941 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002942 break;
2943
Stephen Coe705e5712010-02-16 11:29:44 -05002944 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002945 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002946 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002947 case 0x1f: /* Unspecified error */
2948 if (conn->out && conn->attempt < 2) {
2949 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2950 (hdev->esco_type & EDR_ESCO_MASK);
2951 hci_setup_sync(conn, conn->link->handle);
2952 goto unlock;
2953 }
2954 /* fall through */
2955
2956 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002957 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002958 break;
2959 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002960
2961 hci_proto_connect_cfm(conn, ev->status);
2962 if (ev->status)
2963 hci_conn_del(conn);
2964
2965unlock:
2966 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002967}
2968
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002969static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2970 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002971{
2972 struct inquiry_data data;
2973 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2974 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302975 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002976
2977 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2978
2979 if (!num_rsp)
2980 return;
2981
Andre Guedes1519cc12012-03-21 00:03:38 -03002982 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2983 return;
2984
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002985 hci_dev_lock(hdev);
2986
Johan Hedberge17acd42011-03-30 23:57:16 +03002987 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002988 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002989
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002990 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002991 data.pscan_rep_mode = info->pscan_rep_mode;
2992 data.pscan_period_mode = info->pscan_period_mode;
2993 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002994 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002995 data.clock_offset = info->clock_offset;
2996 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002997 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002998
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002999 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003000 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003001 sizeof(info->data),
3002 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003003 else
3004 name_known = true;
3005
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003006 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003007 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303008 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003009 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003010 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303011 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003012 }
3013
3014 hci_dev_unlock(hdev);
3015}
3016
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003017static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3018 struct sk_buff *skb)
3019{
3020 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3021 struct hci_conn *conn;
3022
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003023 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003024 __le16_to_cpu(ev->handle));
3025
3026 hci_dev_lock(hdev);
3027
3028 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3029 if (!conn)
3030 goto unlock;
3031
3032 if (!ev->status)
3033 conn->sec_level = conn->pending_sec_level;
3034
3035 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3036
3037 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003038 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003039 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003040 goto unlock;
3041 }
3042
3043 if (conn->state == BT_CONFIG) {
3044 if (!ev->status)
3045 conn->state = BT_CONNECTED;
3046
3047 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003048 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003049 } else {
3050 hci_auth_cfm(conn, ev->status);
3051
3052 hci_conn_hold(conn);
3053 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003054 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003055 }
3056
3057unlock:
3058 hci_dev_unlock(hdev);
3059}
3060
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003061static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003062{
3063 /* If remote requests dedicated bonding follow that lead */
3064 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3065 /* If both remote and local IO capabilities allow MITM
3066 * protection then require it, otherwise don't */
3067 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3068 return 0x02;
3069 else
3070 return 0x03;
3071 }
3072
3073 /* If remote requests no-bonding follow that lead */
3074 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003075 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003076
3077 return conn->auth_type;
3078}
3079
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003080static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003081{
3082 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3083 struct hci_conn *conn;
3084
3085 BT_DBG("%s", hdev->name);
3086
3087 hci_dev_lock(hdev);
3088
3089 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003090 if (!conn)
3091 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003092
Johan Hedberg03b555e2011-01-04 15:40:05 +02003093 hci_conn_hold(conn);
3094
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003095 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003096 goto unlock;
3097
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003098 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003099 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003100 struct hci_cp_io_capability_reply cp;
3101
3102 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303103 /* Change the IO capability from KeyboardDisplay
3104 * to DisplayYesNo as it is not supported by BT spec. */
3105 cp.capability = (conn->io_capability == 0x04) ?
3106 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003107 conn->auth_type = hci_get_auth_req(conn);
3108 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003109
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003110 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3111 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003112 cp.oob_data = 0x01;
3113 else
3114 cp.oob_data = 0x00;
3115
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003116 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003117 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003118 } else {
3119 struct hci_cp_io_capability_neg_reply cp;
3120
3121 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003122 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003123
3124 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003125 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003126 }
3127
3128unlock:
3129 hci_dev_unlock(hdev);
3130}
3131
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003132static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003133{
3134 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3135 struct hci_conn *conn;
3136
3137 BT_DBG("%s", hdev->name);
3138
3139 hci_dev_lock(hdev);
3140
3141 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3142 if (!conn)
3143 goto unlock;
3144
Johan Hedberg03b555e2011-01-04 15:40:05 +02003145 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003146 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003147 if (ev->oob_data)
3148 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003149
3150unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003151 hci_dev_unlock(hdev);
3152}
3153
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003154static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3155 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003156{
3157 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003158 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003159 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003160
3161 BT_DBG("%s", hdev->name);
3162
3163 hci_dev_lock(hdev);
3164
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003165 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003166 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003167
Johan Hedberg7a828902011-04-28 11:28:53 -07003168 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3169 if (!conn)
3170 goto unlock;
3171
3172 loc_mitm = (conn->auth_type & 0x01);
3173 rem_mitm = (conn->remote_auth & 0x01);
3174
3175 /* If we require MITM but the remote device can't provide that
3176 * (it has NoInputNoOutput) then reject the confirmation
3177 * request. The only exception is when we're dedicated bonding
3178 * initiators (connect_cfm_cb set) since then we always have the MITM
3179 * bit set. */
3180 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3181 BT_DBG("Rejecting request: remote device can't provide MITM");
3182 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003183 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003184 goto unlock;
3185 }
3186
3187 /* If no side requires MITM protection; auto-accept */
3188 if ((!loc_mitm || conn->remote_cap == 0x03) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003189 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003190
3191 /* If we're not the initiators request authorization to
3192 * proceed from user space (mgmt_user_confirm with
3193 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003194 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003195 BT_DBG("Confirming auto-accept as acceptor");
3196 confirm_hint = 1;
3197 goto confirm;
3198 }
3199
Johan Hedberg9f616562011-04-28 11:28:54 -07003200 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003201 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003202
3203 if (hdev->auto_accept_delay > 0) {
3204 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3205 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3206 goto unlock;
3207 }
3208
Johan Hedberg7a828902011-04-28 11:28:53 -07003209 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003210 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003211 goto unlock;
3212 }
3213
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003214confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003215 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003216 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003217
3218unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003219 hci_dev_unlock(hdev);
3220}
3221
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003222static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3223 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003224{
3225 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3226
3227 BT_DBG("%s", hdev->name);
3228
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003229 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003230 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003231}
3232
Johan Hedberg92a25252012-09-06 18:39:26 +03003233static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3234 struct sk_buff *skb)
3235{
3236 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3237 struct hci_conn *conn;
3238
3239 BT_DBG("%s", hdev->name);
3240
3241 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3242 if (!conn)
3243 return;
3244
3245 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3246 conn->passkey_entered = 0;
3247
3248 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3249 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3250 conn->dst_type, conn->passkey_notify,
3251 conn->passkey_entered);
3252}
3253
3254static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3255{
3256 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3257 struct hci_conn *conn;
3258
3259 BT_DBG("%s", hdev->name);
3260
3261 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3262 if (!conn)
3263 return;
3264
3265 switch (ev->type) {
3266 case HCI_KEYPRESS_STARTED:
3267 conn->passkey_entered = 0;
3268 return;
3269
3270 case HCI_KEYPRESS_ENTERED:
3271 conn->passkey_entered++;
3272 break;
3273
3274 case HCI_KEYPRESS_ERASED:
3275 conn->passkey_entered--;
3276 break;
3277
3278 case HCI_KEYPRESS_CLEARED:
3279 conn->passkey_entered = 0;
3280 break;
3281
3282 case HCI_KEYPRESS_COMPLETED:
3283 return;
3284 }
3285
3286 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3287 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3288 conn->dst_type, conn->passkey_notify,
3289 conn->passkey_entered);
3290}
3291
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003292static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3293 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003294{
3295 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3296 struct hci_conn *conn;
3297
3298 BT_DBG("%s", hdev->name);
3299
3300 hci_dev_lock(hdev);
3301
3302 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003303 if (!conn)
3304 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003305
Johan Hedberg2a611692011-02-19 12:06:00 -03003306 /* To avoid duplicate auth_failed events to user space we check
3307 * the HCI_CONN_AUTH_PEND flag which will be set if we
3308 * initiated the authentication. A traditional auth_complete
3309 * event gets always produced as initiator and is also mapped to
3310 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003311 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003312 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003313 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003314
David Herrmann76a68ba2013-04-06 20:28:37 +02003315 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003316
3317unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003318 hci_dev_unlock(hdev);
3319}
3320
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003321static void hci_remote_host_features_evt(struct hci_dev *hdev,
3322 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003323{
3324 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3325 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003326 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003327
3328 BT_DBG("%s", hdev->name);
3329
3330 hci_dev_lock(hdev);
3331
Johan Hedbergcad718e2013-04-17 15:00:51 +03003332 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3333 if (conn)
3334 memcpy(conn->features[1], ev->features, 8);
3335
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003336 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3337 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003338 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003339
3340 hci_dev_unlock(hdev);
3341}
3342
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003343static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3344 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003345{
3346 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3347 struct oob_data *data;
3348
3349 BT_DBG("%s", hdev->name);
3350
3351 hci_dev_lock(hdev);
3352
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003353 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003354 goto unlock;
3355
Szymon Janc2763eda2011-03-22 13:12:22 +01003356 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3357 if (data) {
3358 struct hci_cp_remote_oob_data_reply cp;
3359
3360 bacpy(&cp.bdaddr, &ev->bdaddr);
3361 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3362 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3363
3364 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003365 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003366 } else {
3367 struct hci_cp_remote_oob_data_neg_reply cp;
3368
3369 bacpy(&cp.bdaddr, &ev->bdaddr);
3370 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003371 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003372 }
3373
Szymon Jance1ba1f12011-04-06 13:01:59 +02003374unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003375 hci_dev_unlock(hdev);
3376}
3377
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003378static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3379 struct sk_buff *skb)
3380{
3381 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3382 struct hci_conn *hcon, *bredr_hcon;
3383
3384 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3385 ev->status);
3386
3387 hci_dev_lock(hdev);
3388
3389 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3390 if (!hcon) {
3391 hci_dev_unlock(hdev);
3392 return;
3393 }
3394
3395 if (ev->status) {
3396 hci_conn_del(hcon);
3397 hci_dev_unlock(hdev);
3398 return;
3399 }
3400
3401 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3402
3403 hcon->state = BT_CONNECTED;
3404 bacpy(&hcon->dst, &bredr_hcon->dst);
3405
3406 hci_conn_hold(hcon);
3407 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003408 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003409
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003410 hci_conn_add_sysfs(hcon);
3411
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003412 amp_physical_cfm(bredr_hcon, hcon);
3413
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003414 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003415}
3416
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003417static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3418{
3419 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3420 struct hci_conn *hcon;
3421 struct hci_chan *hchan;
3422 struct amp_mgr *mgr;
3423
3424 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3425 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3426 ev->status);
3427
3428 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3429 if (!hcon)
3430 return;
3431
3432 /* Create AMP hchan */
3433 hchan = hci_chan_create(hcon);
3434 if (!hchan)
3435 return;
3436
3437 hchan->handle = le16_to_cpu(ev->handle);
3438
3439 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3440
3441 mgr = hcon->amp_mgr;
3442 if (mgr && mgr->bredr_chan) {
3443 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3444
3445 l2cap_chan_lock(bredr_chan);
3446
3447 bredr_chan->conn->mtu = hdev->block_mtu;
3448 l2cap_logical_cfm(bredr_chan, hchan, 0);
3449 hci_conn_hold(hcon);
3450
3451 l2cap_chan_unlock(bredr_chan);
3452 }
3453}
3454
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003455static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3456 struct sk_buff *skb)
3457{
3458 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3459 struct hci_chan *hchan;
3460
3461 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3462 le16_to_cpu(ev->handle), ev->status);
3463
3464 if (ev->status)
3465 return;
3466
3467 hci_dev_lock(hdev);
3468
3469 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3470 if (!hchan)
3471 goto unlock;
3472
3473 amp_destroy_logical_link(hchan, ev->reason);
3474
3475unlock:
3476 hci_dev_unlock(hdev);
3477}
3478
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003479static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3480 struct sk_buff *skb)
3481{
3482 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3483 struct hci_conn *hcon;
3484
3485 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3486
3487 if (ev->status)
3488 return;
3489
3490 hci_dev_lock(hdev);
3491
3492 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3493 if (hcon) {
3494 hcon->state = BT_CLOSED;
3495 hci_conn_del(hcon);
3496 }
3497
3498 hci_dev_unlock(hdev);
3499}
3500
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003501static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003502{
3503 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3504 struct hci_conn *conn;
3505
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003506 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003507
3508 hci_dev_lock(hdev);
3509
Andre Guedesb47a09b2012-07-27 15:10:15 -03003510 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003511 if (!conn) {
3512 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3513 if (!conn) {
3514 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003515 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003516 }
Andre Guedes29b79882011-05-31 14:20:54 -03003517
3518 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003519
3520 if (ev->role == LE_CONN_ROLE_MASTER) {
3521 conn->out = true;
3522 conn->link_mode |= HCI_LM_MASTER;
3523 }
Ville Tervob62f3282011-02-10 22:38:50 -03003524 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003525
Andre Guedescd17dec2012-07-27 15:10:16 -03003526 if (ev->status) {
3527 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3528 conn->dst_type, ev->status);
3529 hci_proto_connect_cfm(conn, ev->status);
3530 conn->state = BT_CLOSED;
3531 hci_conn_del(conn);
3532 goto unlock;
3533 }
3534
Johan Hedbergb644ba32012-01-17 21:48:47 +02003535 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3536 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003537 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003538
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003539 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003540 conn->handle = __le16_to_cpu(ev->handle);
3541 conn->state = BT_CONNECTED;
3542
Ville Tervofcd89c02011-02-10 22:38:47 -03003543 hci_conn_add_sysfs(conn);
3544
3545 hci_proto_connect_cfm(conn, ev->status);
3546
3547unlock:
3548 hci_dev_unlock(hdev);
3549}
3550
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003551static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003552{
Andre Guedese95beb42011-09-26 20:48:35 -03003553 u8 num_reports = skb->data[0];
3554 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003555 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003556
Andre Guedese95beb42011-09-26 20:48:35 -03003557 while (num_reports--) {
3558 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003559
Andre Guedes3c9e9192012-01-10 18:20:50 -03003560 rssi = ev->data[ev->length];
3561 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003562 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003563
Andre Guedese95beb42011-09-26 20:48:35 -03003564 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003565 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003566}
3567
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003568static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003569{
3570 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3571 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003572 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003573 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003574 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003575
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003576 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003577
3578 hci_dev_lock(hdev);
3579
3580 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003581 if (conn == NULL)
3582 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003583
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003584 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3585 if (ltk == NULL)
3586 goto not_found;
3587
3588 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003589 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003590
3591 if (ltk->authenticated)
3592 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003593
3594 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3595
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003596 if (ltk->type & HCI_SMP_STK) {
3597 list_del(&ltk->list);
3598 kfree(ltk);
3599 }
3600
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003601 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003602
3603 return;
3604
3605not_found:
3606 neg.handle = ev->handle;
3607 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3608 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003609}
3610
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003611static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003612{
3613 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3614
3615 skb_pull(skb, sizeof(*le_ev));
3616
3617 switch (le_ev->subevent) {
3618 case HCI_EV_LE_CONN_COMPLETE:
3619 hci_le_conn_complete_evt(hdev, skb);
3620 break;
3621
Andre Guedes9aa04c92011-05-26 16:23:51 -03003622 case HCI_EV_LE_ADVERTISING_REPORT:
3623 hci_le_adv_report_evt(hdev, skb);
3624 break;
3625
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003626 case HCI_EV_LE_LTK_REQ:
3627 hci_le_ltk_request_evt(hdev, skb);
3628 break;
3629
Ville Tervofcd89c02011-02-10 22:38:47 -03003630 default:
3631 break;
3632 }
3633}
3634
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003635static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3636{
3637 struct hci_ev_channel_selected *ev = (void *) skb->data;
3638 struct hci_conn *hcon;
3639
3640 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3641
3642 skb_pull(skb, sizeof(*ev));
3643
3644 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3645 if (!hcon)
3646 return;
3647
3648 amp_read_loc_assoc_final_data(hdev, hcon);
3649}
3650
Linus Torvalds1da177e2005-04-16 15:20:36 -07003651void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3652{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003653 struct hci_event_hdr *hdr = (void *) skb->data;
3654 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003655
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003656 hci_dev_lock(hdev);
3657
3658 /* Received events are (currently) only needed when a request is
3659 * ongoing so avoid unnecessary memory allocation.
3660 */
3661 if (hdev->req_status == HCI_REQ_PEND) {
3662 kfree_skb(hdev->recv_evt);
3663 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3664 }
3665
3666 hci_dev_unlock(hdev);
3667
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3669
Johan Hedberg02350a72013-04-03 21:50:29 +03003670 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
3671 struct hci_command_hdr *hdr = (void *) hdev->sent_cmd->data;
3672 u16 opcode = __le16_to_cpu(hdr->opcode);
3673
3674 hci_req_cmd_complete(hdev, opcode, 0);
3675 }
3676
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003677 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003678 case HCI_EV_INQUIRY_COMPLETE:
3679 hci_inquiry_complete_evt(hdev, skb);
3680 break;
3681
3682 case HCI_EV_INQUIRY_RESULT:
3683 hci_inquiry_result_evt(hdev, skb);
3684 break;
3685
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003686 case HCI_EV_CONN_COMPLETE:
3687 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003688 break;
3689
Linus Torvalds1da177e2005-04-16 15:20:36 -07003690 case HCI_EV_CONN_REQUEST:
3691 hci_conn_request_evt(hdev, skb);
3692 break;
3693
Linus Torvalds1da177e2005-04-16 15:20:36 -07003694 case HCI_EV_DISCONN_COMPLETE:
3695 hci_disconn_complete_evt(hdev, skb);
3696 break;
3697
Linus Torvalds1da177e2005-04-16 15:20:36 -07003698 case HCI_EV_AUTH_COMPLETE:
3699 hci_auth_complete_evt(hdev, skb);
3700 break;
3701
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003702 case HCI_EV_REMOTE_NAME:
3703 hci_remote_name_evt(hdev, skb);
3704 break;
3705
Linus Torvalds1da177e2005-04-16 15:20:36 -07003706 case HCI_EV_ENCRYPT_CHANGE:
3707 hci_encrypt_change_evt(hdev, skb);
3708 break;
3709
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003710 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3711 hci_change_link_key_complete_evt(hdev, skb);
3712 break;
3713
3714 case HCI_EV_REMOTE_FEATURES:
3715 hci_remote_features_evt(hdev, skb);
3716 break;
3717
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003718 case HCI_EV_CMD_COMPLETE:
3719 hci_cmd_complete_evt(hdev, skb);
3720 break;
3721
3722 case HCI_EV_CMD_STATUS:
3723 hci_cmd_status_evt(hdev, skb);
3724 break;
3725
3726 case HCI_EV_ROLE_CHANGE:
3727 hci_role_change_evt(hdev, skb);
3728 break;
3729
3730 case HCI_EV_NUM_COMP_PKTS:
3731 hci_num_comp_pkts_evt(hdev, skb);
3732 break;
3733
3734 case HCI_EV_MODE_CHANGE:
3735 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003736 break;
3737
3738 case HCI_EV_PIN_CODE_REQ:
3739 hci_pin_code_request_evt(hdev, skb);
3740 break;
3741
3742 case HCI_EV_LINK_KEY_REQ:
3743 hci_link_key_request_evt(hdev, skb);
3744 break;
3745
3746 case HCI_EV_LINK_KEY_NOTIFY:
3747 hci_link_key_notify_evt(hdev, skb);
3748 break;
3749
3750 case HCI_EV_CLOCK_OFFSET:
3751 hci_clock_offset_evt(hdev, skb);
3752 break;
3753
Marcel Holtmanna8746412008-07-14 20:13:46 +02003754 case HCI_EV_PKT_TYPE_CHANGE:
3755 hci_pkt_type_change_evt(hdev, skb);
3756 break;
3757
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003758 case HCI_EV_PSCAN_REP_MODE:
3759 hci_pscan_rep_mode_evt(hdev, skb);
3760 break;
3761
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003762 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3763 hci_inquiry_result_with_rssi_evt(hdev, skb);
3764 break;
3765
3766 case HCI_EV_REMOTE_EXT_FEATURES:
3767 hci_remote_ext_features_evt(hdev, skb);
3768 break;
3769
3770 case HCI_EV_SYNC_CONN_COMPLETE:
3771 hci_sync_conn_complete_evt(hdev, skb);
3772 break;
3773
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003774 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3775 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776 break;
3777
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003778 case HCI_EV_KEY_REFRESH_COMPLETE:
3779 hci_key_refresh_complete_evt(hdev, skb);
3780 break;
3781
Marcel Holtmann04936842008-07-14 20:13:48 +02003782 case HCI_EV_IO_CAPA_REQUEST:
3783 hci_io_capa_request_evt(hdev, skb);
3784 break;
3785
Johan Hedberg03b555e2011-01-04 15:40:05 +02003786 case HCI_EV_IO_CAPA_REPLY:
3787 hci_io_capa_reply_evt(hdev, skb);
3788 break;
3789
Johan Hedberga5c29682011-02-19 12:05:57 -03003790 case HCI_EV_USER_CONFIRM_REQUEST:
3791 hci_user_confirm_request_evt(hdev, skb);
3792 break;
3793
Brian Gix1143d452011-11-23 08:28:34 -08003794 case HCI_EV_USER_PASSKEY_REQUEST:
3795 hci_user_passkey_request_evt(hdev, skb);
3796 break;
3797
Johan Hedberg92a25252012-09-06 18:39:26 +03003798 case HCI_EV_USER_PASSKEY_NOTIFY:
3799 hci_user_passkey_notify_evt(hdev, skb);
3800 break;
3801
3802 case HCI_EV_KEYPRESS_NOTIFY:
3803 hci_keypress_notify_evt(hdev, skb);
3804 break;
3805
Marcel Holtmann04936842008-07-14 20:13:48 +02003806 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3807 hci_simple_pair_complete_evt(hdev, skb);
3808 break;
3809
Marcel Holtmann41a96212008-07-14 20:13:48 +02003810 case HCI_EV_REMOTE_HOST_FEATURES:
3811 hci_remote_host_features_evt(hdev, skb);
3812 break;
3813
Ville Tervofcd89c02011-02-10 22:38:47 -03003814 case HCI_EV_LE_META:
3815 hci_le_meta_evt(hdev, skb);
3816 break;
3817
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003818 case HCI_EV_CHANNEL_SELECTED:
3819 hci_chan_selected_evt(hdev, skb);
3820 break;
3821
Szymon Janc2763eda2011-03-22 13:12:22 +01003822 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3823 hci_remote_oob_data_request_evt(hdev, skb);
3824 break;
3825
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003826 case HCI_EV_PHY_LINK_COMPLETE:
3827 hci_phy_link_complete_evt(hdev, skb);
3828 break;
3829
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003830 case HCI_EV_LOGICAL_LINK_COMPLETE:
3831 hci_loglink_complete_evt(hdev, skb);
3832 break;
3833
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003834 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3835 hci_disconn_loglink_complete_evt(hdev, skb);
3836 break;
3837
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003838 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3839 hci_disconn_phylink_complete_evt(hdev, skb);
3840 break;
3841
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003842 case HCI_EV_NUM_COMP_BLOCKS:
3843 hci_num_comp_blocks_evt(hdev, skb);
3844 break;
3845
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003846 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003847 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003848 break;
3849 }
3850
3851 kfree_skb(skb);
3852 hdev->stat.evt_rx++;
3853}