blob: faaf1f31345d6f8a469e3ceaa7812f7294819d76 [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 Guedes76a388be2013-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 Guedes76a388be2013-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);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200977 break;
978
979 default:
980 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
981 break;
Andre Guedes35815082011-05-26 16:23:53 -0300982 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300983}
984
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200985static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
986 struct sk_buff *skb)
987{
988 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
989
990 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
991
992 if (!rp->status)
993 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200994}
995
Johan Hedberg9b008c02013-01-22 14:02:01 +0200996static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
997 struct sk_buff *skb)
998{
999 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1000
1001 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1002
1003 if (!rp->status)
1004 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001005}
1006
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001007static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1008 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001009{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001010 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001011 __u8 status = *((__u8 *) skb->data);
1012
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001013 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001014
Johan Hedberg06199cf2012-02-22 16:37:11 +02001015 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001016 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001017 return;
1018
Johan Hedberg8f984df2012-02-28 01:07:22 +02001019 if (!status) {
1020 if (sent->le)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001021 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001022 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001023 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001024
1025 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001026 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001027 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001028 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001029 }
1030
1031 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001032 !test_bit(HCI_INIT, &hdev->flags))
Johan Hedberg8f984df2012-02-28 01:07:22 +02001033 mgmt_le_enable_complete(hdev, sent->le, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001034}
1035
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001036static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1037 struct sk_buff *skb)
1038{
1039 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1040
1041 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1042 hdev->name, rp->status, rp->phy_handle);
1043
1044 if (rp->status)
1045 return;
1046
1047 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1048}
1049
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001050static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001051{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001052 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001053
1054 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001055 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001056 return;
1057 }
1058
Andre Guedes89352e72011-11-04 14:16:53 -03001059 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001060}
1061
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001062static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001064 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001067 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001068
1069 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 if (!cp)
1071 return;
1072
1073 hci_dev_lock(hdev);
1074
1075 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1076
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001077 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078
1079 if (status) {
1080 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001081 if (status != 0x0c || conn->attempt > 2) {
1082 conn->state = BT_CLOSED;
1083 hci_proto_connect_cfm(conn, status);
1084 hci_conn_del(conn);
1085 } else
1086 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 }
1088 } else {
1089 if (!conn) {
1090 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1091 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001092 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093 conn->link_mode |= HCI_LM_MASTER;
1094 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001095 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 }
1097 }
1098
1099 hci_dev_unlock(hdev);
1100}
1101
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001102static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001104 struct hci_cp_add_sco *cp;
1105 struct hci_conn *acl, *sco;
1106 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001108 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001109
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001110 if (!status)
1111 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001113 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1114 if (!cp)
1115 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001117 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001119 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001120
1121 hci_dev_lock(hdev);
1122
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001123 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001124 if (acl) {
1125 sco = acl->link;
1126 if (sco) {
1127 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001128
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001129 hci_proto_connect_cfm(sco, status);
1130 hci_conn_del(sco);
1131 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001132 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001133
1134 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135}
1136
Marcel Holtmannf8558552008-07-14 20:13:49 +02001137static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1138{
1139 struct hci_cp_auth_requested *cp;
1140 struct hci_conn *conn;
1141
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001142 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001143
1144 if (!status)
1145 return;
1146
1147 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1148 if (!cp)
1149 return;
1150
1151 hci_dev_lock(hdev);
1152
1153 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1154 if (conn) {
1155 if (conn->state == BT_CONFIG) {
1156 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001157 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001158 }
1159 }
1160
1161 hci_dev_unlock(hdev);
1162}
1163
1164static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1165{
1166 struct hci_cp_set_conn_encrypt *cp;
1167 struct hci_conn *conn;
1168
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001169 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001170
1171 if (!status)
1172 return;
1173
1174 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1175 if (!cp)
1176 return;
1177
1178 hci_dev_lock(hdev);
1179
1180 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1181 if (conn) {
1182 if (conn->state == BT_CONFIG) {
1183 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001184 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001185 }
1186 }
1187
1188 hci_dev_unlock(hdev);
1189}
1190
Johan Hedberg127178d2010-11-18 22:22:29 +02001191static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001192 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001193{
Johan Hedberg392599b2010-11-18 22:22:28 +02001194 if (conn->state != BT_CONFIG || !conn->out)
1195 return 0;
1196
Johan Hedberg765c2a92011-01-19 12:06:52 +05301197 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001198 return 0;
1199
1200 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001201 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001202 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1203 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001204 return 0;
1205
Johan Hedberg392599b2010-11-18 22:22:28 +02001206 return 1;
1207}
1208
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001209static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001210 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001211{
1212 struct hci_cp_remote_name_req cp;
1213
1214 memset(&cp, 0, sizeof(cp));
1215
1216 bacpy(&cp.bdaddr, &e->data.bdaddr);
1217 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1218 cp.pscan_mode = e->data.pscan_mode;
1219 cp.clock_offset = e->data.clock_offset;
1220
1221 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1222}
1223
Johan Hedbergb644ba32012-01-17 21:48:47 +02001224static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001225{
1226 struct discovery_state *discov = &hdev->discovery;
1227 struct inquiry_entry *e;
1228
Johan Hedbergb644ba32012-01-17 21:48:47 +02001229 if (list_empty(&discov->resolve))
1230 return false;
1231
1232 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001233 if (!e)
1234 return false;
1235
Johan Hedbergb644ba32012-01-17 21:48:47 +02001236 if (hci_resolve_name(hdev, e) == 0) {
1237 e->name_state = NAME_PENDING;
1238 return true;
1239 }
1240
1241 return false;
1242}
1243
1244static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001245 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001246{
1247 struct discovery_state *discov = &hdev->discovery;
1248 struct inquiry_entry *e;
1249
1250 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001251 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1252 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001253
1254 if (discov->state == DISCOVERY_STOPPED)
1255 return;
1256
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001257 if (discov->state == DISCOVERY_STOPPING)
1258 goto discov_complete;
1259
1260 if (discov->state != DISCOVERY_RESOLVING)
1261 return;
1262
1263 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001264 /* If the device was not found in a list of found devices names of which
1265 * are pending. there is no need to continue resolving a next name as it
1266 * will be done upon receiving another Remote Name Request Complete
1267 * Event */
1268 if (!e)
1269 return;
1270
1271 list_del(&e->list);
1272 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001273 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001274 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1275 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001276 } else {
1277 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001278 }
1279
Johan Hedbergb644ba32012-01-17 21:48:47 +02001280 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001281 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001282
1283discov_complete:
1284 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1285}
1286
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001287static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1288{
Johan Hedberg127178d2010-11-18 22:22:29 +02001289 struct hci_cp_remote_name_req *cp;
1290 struct hci_conn *conn;
1291
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001292 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001293
1294 /* If successful wait for the name req complete event before
1295 * checking for the need to do authentication */
1296 if (!status)
1297 return;
1298
1299 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1300 if (!cp)
1301 return;
1302
1303 hci_dev_lock(hdev);
1304
1305 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001306
1307 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1308 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1309
Johan Hedberg79c6c702011-04-28 11:28:55 -07001310 if (!conn)
1311 goto unlock;
1312
1313 if (!hci_outgoing_auth_needed(hdev, conn))
1314 goto unlock;
1315
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001316 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001317 struct hci_cp_auth_requested cp;
1318 cp.handle = __cpu_to_le16(conn->handle);
1319 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1320 }
1321
Johan Hedberg79c6c702011-04-28 11:28:55 -07001322unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001323 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001324}
1325
Marcel Holtmann769be972008-07-14 20:13:49 +02001326static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1327{
1328 struct hci_cp_read_remote_features *cp;
1329 struct hci_conn *conn;
1330
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001331 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001332
1333 if (!status)
1334 return;
1335
1336 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1337 if (!cp)
1338 return;
1339
1340 hci_dev_lock(hdev);
1341
1342 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1343 if (conn) {
1344 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001345 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001346 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001347 }
1348 }
1349
1350 hci_dev_unlock(hdev);
1351}
1352
1353static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1354{
1355 struct hci_cp_read_remote_ext_features *cp;
1356 struct hci_conn *conn;
1357
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001358 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001359
1360 if (!status)
1361 return;
1362
1363 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1364 if (!cp)
1365 return;
1366
1367 hci_dev_lock(hdev);
1368
1369 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1370 if (conn) {
1371 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001372 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001373 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001374 }
1375 }
1376
1377 hci_dev_unlock(hdev);
1378}
1379
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001380static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1381{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001382 struct hci_cp_setup_sync_conn *cp;
1383 struct hci_conn *acl, *sco;
1384 __u16 handle;
1385
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001386 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001387
1388 if (!status)
1389 return;
1390
1391 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1392 if (!cp)
1393 return;
1394
1395 handle = __le16_to_cpu(cp->handle);
1396
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001397 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001398
1399 hci_dev_lock(hdev);
1400
1401 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001402 if (acl) {
1403 sco = acl->link;
1404 if (sco) {
1405 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001406
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001407 hci_proto_connect_cfm(sco, status);
1408 hci_conn_del(sco);
1409 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001410 }
1411
1412 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001413}
1414
1415static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1416{
1417 struct hci_cp_sniff_mode *cp;
1418 struct hci_conn *conn;
1419
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001420 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001421
1422 if (!status)
1423 return;
1424
1425 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1426 if (!cp)
1427 return;
1428
1429 hci_dev_lock(hdev);
1430
1431 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001432 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001433 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001434
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001435 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001436 hci_sco_setup(conn, status);
1437 }
1438
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001439 hci_dev_unlock(hdev);
1440}
1441
1442static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1443{
1444 struct hci_cp_exit_sniff_mode *cp;
1445 struct hci_conn *conn;
1446
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001447 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001448
1449 if (!status)
1450 return;
1451
1452 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1453 if (!cp)
1454 return;
1455
1456 hci_dev_lock(hdev);
1457
1458 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001459 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001460 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001461
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001462 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001463 hci_sco_setup(conn, status);
1464 }
1465
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001466 hci_dev_unlock(hdev);
1467}
1468
Johan Hedberg88c3df12012-02-09 14:27:38 +02001469static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1470{
1471 struct hci_cp_disconnect *cp;
1472 struct hci_conn *conn;
1473
1474 if (!status)
1475 return;
1476
1477 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1478 if (!cp)
1479 return;
1480
1481 hci_dev_lock(hdev);
1482
1483 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1484 if (conn)
1485 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001486 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001487
1488 hci_dev_unlock(hdev);
1489}
1490
Ville Tervofcd89c02011-02-10 22:38:47 -03001491static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1492{
Ville Tervofcd89c02011-02-10 22:38:47 -03001493 struct hci_conn *conn;
1494
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001495 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Ville Tervofcd89c02011-02-10 22:38:47 -03001496
Ville Tervofcd89c02011-02-10 22:38:47 -03001497 if (status) {
Andre Guedesf00a06a2012-07-27 15:10:13 -03001498 hci_dev_lock(hdev);
Ville Tervofcd89c02011-02-10 22:38:47 -03001499
Andre Guedes0c95ab72012-07-27 15:10:14 -03001500 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001501 if (!conn) {
1502 hci_dev_unlock(hdev);
1503 return;
1504 }
1505
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001506 BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001507
1508 conn->state = BT_CLOSED;
Andre Guedes0c95ab72012-07-27 15:10:14 -03001509 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Andre Guedesf00a06a2012-07-27 15:10:13 -03001510 conn->dst_type, status);
1511 hci_proto_connect_cfm(conn, status);
1512 hci_conn_del(conn);
1513
1514 hci_dev_unlock(hdev);
1515 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001516}
1517
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001518static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1519{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001520 struct hci_cp_create_phy_link *cp;
1521
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001522 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001523
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001524 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1525 if (!cp)
1526 return;
1527
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001528 hci_dev_lock(hdev);
1529
1530 if (status) {
1531 struct hci_conn *hcon;
1532
1533 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1534 if (hcon)
1535 hci_conn_del(hcon);
1536 } else {
1537 amp_write_remote_assoc(hdev, cp->phy_handle);
1538 }
1539
1540 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001541}
1542
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001543static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1544{
1545 struct hci_cp_accept_phy_link *cp;
1546
1547 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1548
1549 if (status)
1550 return;
1551
1552 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1553 if (!cp)
1554 return;
1555
1556 amp_write_remote_assoc(hdev, cp->phy_handle);
1557}
1558
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001559static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001560{
1561 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001562 struct discovery_state *discov = &hdev->discovery;
1563 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001564
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001565 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001566
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001567 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001568
1569 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1570 return;
1571
Andre Guedes3e13fa12013-03-27 20:04:56 -03001572 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1573 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1574
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001575 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001576 return;
1577
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001578 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001579
Andre Guedes343f9352012-02-17 20:39:37 -03001580 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001581 goto unlock;
1582
1583 if (list_empty(&discov->resolve)) {
1584 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1585 goto unlock;
1586 }
1587
1588 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1589 if (e && hci_resolve_name(hdev, e) == 0) {
1590 e->name_state = NAME_PENDING;
1591 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1592 } else {
1593 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1594 }
1595
1596unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001597 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001598}
1599
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001600static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001602 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001603 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 int num_rsp = *((__u8 *) skb->data);
1605
1606 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1607
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001608 if (!num_rsp)
1609 return;
1610
Andre Guedes1519cc12012-03-21 00:03:38 -03001611 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1612 return;
1613
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001615
Johan Hedberge17acd42011-03-30 23:57:16 +03001616 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001617 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001618
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619 bacpy(&data.bdaddr, &info->bdaddr);
1620 data.pscan_rep_mode = info->pscan_rep_mode;
1621 data.pscan_period_mode = info->pscan_period_mode;
1622 data.pscan_mode = info->pscan_mode;
1623 memcpy(data.dev_class, info->dev_class, 3);
1624 data.clock_offset = info->clock_offset;
1625 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001626 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001627
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001628 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001629 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001630 info->dev_class, 0, !name_known, ssp, NULL,
1631 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001633
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 hci_dev_unlock(hdev);
1635}
1636
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001637static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001639 struct hci_ev_conn_complete *ev = (void *) skb->data;
1640 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001642 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001643
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001645
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001646 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001647 if (!conn) {
1648 if (ev->link_type != SCO_LINK)
1649 goto unlock;
1650
1651 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1652 if (!conn)
1653 goto unlock;
1654
1655 conn->type = SCO_LINK;
1656 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001657
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001658 if (!ev->status) {
1659 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001660
1661 if (conn->type == ACL_LINK) {
1662 conn->state = BT_CONFIG;
1663 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001664
1665 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1666 !hci_find_link_key(hdev, &ev->bdaddr))
1667 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1668 else
1669 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001670 } else
1671 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001672
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001673 hci_conn_add_sysfs(conn);
1674
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001675 if (test_bit(HCI_AUTH, &hdev->flags))
1676 conn->link_mode |= HCI_LM_AUTH;
1677
1678 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1679 conn->link_mode |= HCI_LM_ENCRYPT;
1680
1681 /* Get remote features */
1682 if (conn->type == ACL_LINK) {
1683 struct hci_cp_read_remote_features cp;
1684 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001685 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001686 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001687 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001688
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001689 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001690 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001691 struct hci_cp_change_conn_ptype cp;
1692 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001693 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001694 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1695 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001696 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001697 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001698 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001699 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001700 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001701 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001702 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001703
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001704 if (conn->type == ACL_LINK)
1705 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001706
Marcel Holtmann769be972008-07-14 20:13:49 +02001707 if (ev->status) {
1708 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001709 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001710 } else if (ev->link_type != ACL_LINK)
1711 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001712
1713unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001715
1716 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717}
1718
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001719static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001721 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 int mask = hdev->link_mode;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001723 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001725 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001726 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001728 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1729 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730
Szymon Janc138d22e2011-02-17 16:44:23 +01001731 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001732 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001734 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736
1737 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001738
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001739 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1740 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001741 memcpy(ie->data.dev_class, ev->dev_class, 3);
1742
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001743 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1744 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001746 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1747 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001748 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 hci_dev_unlock(hdev);
1750 return;
1751 }
1752 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001753
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001755
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 hci_dev_unlock(hdev);
1757
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001758 if (ev->link_type == ACL_LINK ||
1759 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001760 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001761 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001763 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001765 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1766 cp.role = 0x00; /* Become master */
1767 else
1768 cp.role = 0x01; /* Remain slave */
1769
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001770 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1771 &cp);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001772 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001773 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001774 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001775
1776 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001777 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001778
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001779 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1780 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1781 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001782 cp.content_format = cpu_to_le16(hdev->voice_setting);
1783 cp.retrans_effort = 0xff;
1784
1785 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001786 sizeof(cp), &cp);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001787 } else {
1788 conn->state = BT_CONNECT2;
1789 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001790 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 } else {
1792 /* Connection rejected */
1793 struct hci_cp_reject_conn_req cp;
1794
1795 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001796 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001797 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 }
1799}
1800
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001801static u8 hci_to_mgmt_reason(u8 err)
1802{
1803 switch (err) {
1804 case HCI_ERROR_CONNECTION_TIMEOUT:
1805 return MGMT_DEV_DISCONN_TIMEOUT;
1806 case HCI_ERROR_REMOTE_USER_TERM:
1807 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1808 case HCI_ERROR_REMOTE_POWER_OFF:
1809 return MGMT_DEV_DISCONN_REMOTE;
1810 case HCI_ERROR_LOCAL_HOST_TERM:
1811 return MGMT_DEV_DISCONN_LOCAL_HOST;
1812 default:
1813 return MGMT_DEV_DISCONN_UNKNOWN;
1814 }
1815}
1816
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001817static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001819 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001820 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001822 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 hci_dev_lock(hdev);
1825
Marcel Holtmann04837f62006-07-03 10:02:33 +02001826 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001827 if (!conn)
1828 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001829
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001830 if (ev->status == 0)
1831 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832
Johan Hedbergb644ba32012-01-17 21:48:47 +02001833 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001834 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001835 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001836 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001837 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001838 } else {
1839 u8 reason = hci_to_mgmt_reason(ev->reason);
1840
Johan Hedbergafc747a2012-01-15 18:11:07 +02001841 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001842 conn->dst_type, reason);
1843 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001844 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001845
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001846 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301847 if (conn->type == ACL_LINK && conn->flush_key)
1848 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001849 hci_proto_disconn_cfm(conn, ev->reason);
1850 hci_conn_del(conn);
1851 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001852
1853unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854 hci_dev_unlock(hdev);
1855}
1856
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001857static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001858{
1859 struct hci_ev_auth_complete *ev = (void *) skb->data;
1860 struct hci_conn *conn;
1861
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001862 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001863
1864 hci_dev_lock(hdev);
1865
1866 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001867 if (!conn)
1868 goto unlock;
1869
1870 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001871 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001872 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001873 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001874 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001875 conn->link_mode |= HCI_LM_AUTH;
1876 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001877 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001878 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001879 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001880 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001881 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001882
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001883 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1884 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001885
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001886 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001887 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001888 struct hci_cp_set_conn_encrypt cp;
1889 cp.handle = ev->handle;
1890 cp.encrypt = 0x01;
1891 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001892 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001893 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001894 conn->state = BT_CONNECTED;
1895 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001896 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001897 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001898 } else {
1899 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001900
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001901 hci_conn_hold(conn);
1902 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001903 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001904 }
1905
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001906 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001907 if (!ev->status) {
1908 struct hci_cp_set_conn_encrypt cp;
1909 cp.handle = ev->handle;
1910 cp.encrypt = 0x01;
1911 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001912 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001913 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001914 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001915 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001916 }
1917 }
1918
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001919unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001920 hci_dev_unlock(hdev);
1921}
1922
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001923static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001924{
Johan Hedberg127178d2010-11-18 22:22:29 +02001925 struct hci_ev_remote_name *ev = (void *) skb->data;
1926 struct hci_conn *conn;
1927
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001928 BT_DBG("%s", hdev->name);
1929
1930 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001931
1932 hci_dev_lock(hdev);
1933
1934 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001935
1936 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1937 goto check_auth;
1938
1939 if (ev->status == 0)
1940 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001941 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001942 else
1943 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1944
1945check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001946 if (!conn)
1947 goto unlock;
1948
1949 if (!hci_outgoing_auth_needed(hdev, conn))
1950 goto unlock;
1951
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001952 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001953 struct hci_cp_auth_requested cp;
1954 cp.handle = __cpu_to_le16(conn->handle);
1955 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1956 }
1957
Johan Hedberg79c6c702011-04-28 11:28:55 -07001958unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001959 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001960}
1961
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001962static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001963{
1964 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1965 struct hci_conn *conn;
1966
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001967 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001968
1969 hci_dev_lock(hdev);
1970
1971 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1972 if (conn) {
1973 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001974 if (ev->encrypt) {
1975 /* Encryption implies authentication */
1976 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001977 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001978 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001979 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001980 conn->link_mode &= ~HCI_LM_ENCRYPT;
1981 }
1982
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001983 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001984
Gustavo Padovana7d77232012-05-13 03:20:07 -03001985 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03001986 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02001987 hci_conn_drop(conn);
Gustavo Padovana7d77232012-05-13 03:20:07 -03001988 goto unlock;
1989 }
1990
Marcel Holtmannf8558552008-07-14 20:13:49 +02001991 if (conn->state == BT_CONFIG) {
1992 if (!ev->status)
1993 conn->state = BT_CONNECTED;
1994
1995 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001996 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001997 } else
1998 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001999 }
2000
Gustavo Padovana7d77232012-05-13 03:20:07 -03002001unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002002 hci_dev_unlock(hdev);
2003}
2004
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002005static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2006 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002007{
2008 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2009 struct hci_conn *conn;
2010
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002011 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002012
2013 hci_dev_lock(hdev);
2014
2015 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2016 if (conn) {
2017 if (!ev->status)
2018 conn->link_mode |= HCI_LM_SECURE;
2019
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002020 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002021
2022 hci_key_change_cfm(conn, ev->status);
2023 }
2024
2025 hci_dev_unlock(hdev);
2026}
2027
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002028static void hci_remote_features_evt(struct hci_dev *hdev,
2029 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002030{
2031 struct hci_ev_remote_features *ev = (void *) skb->data;
2032 struct hci_conn *conn;
2033
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002034 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002035
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002036 hci_dev_lock(hdev);
2037
2038 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002039 if (!conn)
2040 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002041
Johan Hedbergccd556f2010-11-10 17:11:51 +02002042 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002043 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002044
2045 if (conn->state != BT_CONFIG)
2046 goto unlock;
2047
2048 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2049 struct hci_cp_read_remote_ext_features cp;
2050 cp.handle = ev->handle;
2051 cp.page = 0x01;
2052 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002053 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002054 goto unlock;
2055 }
2056
Johan Hedberg671267b2012-05-12 16:11:50 -03002057 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002058 struct hci_cp_remote_name_req cp;
2059 memset(&cp, 0, sizeof(cp));
2060 bacpy(&cp.bdaddr, &conn->dst);
2061 cp.pscan_rep_mode = 0x02;
2062 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002063 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2064 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002065 conn->dst_type, 0, NULL, 0,
2066 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002067
Johan Hedberg127178d2010-11-18 22:22:29 +02002068 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002069 conn->state = BT_CONNECTED;
2070 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002071 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002072 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002073
Johan Hedbergccd556f2010-11-10 17:11:51 +02002074unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002075 hci_dev_unlock(hdev);
2076}
2077
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002078static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002079{
2080 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002081 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002082 __u16 opcode;
2083
2084 skb_pull(skb, sizeof(*ev));
2085
2086 opcode = __le16_to_cpu(ev->opcode);
2087
2088 switch (opcode) {
2089 case HCI_OP_INQUIRY_CANCEL:
2090 hci_cc_inquiry_cancel(hdev, skb);
2091 break;
2092
Andre Guedes4d934832012-03-21 00:03:35 -03002093 case HCI_OP_PERIODIC_INQ:
2094 hci_cc_periodic_inq(hdev, skb);
2095 break;
2096
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002097 case HCI_OP_EXIT_PERIODIC_INQ:
2098 hci_cc_exit_periodic_inq(hdev, skb);
2099 break;
2100
2101 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2102 hci_cc_remote_name_req_cancel(hdev, skb);
2103 break;
2104
2105 case HCI_OP_ROLE_DISCOVERY:
2106 hci_cc_role_discovery(hdev, skb);
2107 break;
2108
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002109 case HCI_OP_READ_LINK_POLICY:
2110 hci_cc_read_link_policy(hdev, skb);
2111 break;
2112
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002113 case HCI_OP_WRITE_LINK_POLICY:
2114 hci_cc_write_link_policy(hdev, skb);
2115 break;
2116
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002117 case HCI_OP_READ_DEF_LINK_POLICY:
2118 hci_cc_read_def_link_policy(hdev, skb);
2119 break;
2120
2121 case HCI_OP_WRITE_DEF_LINK_POLICY:
2122 hci_cc_write_def_link_policy(hdev, skb);
2123 break;
2124
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002125 case HCI_OP_RESET:
2126 hci_cc_reset(hdev, skb);
2127 break;
2128
2129 case HCI_OP_WRITE_LOCAL_NAME:
2130 hci_cc_write_local_name(hdev, skb);
2131 break;
2132
2133 case HCI_OP_READ_LOCAL_NAME:
2134 hci_cc_read_local_name(hdev, skb);
2135 break;
2136
2137 case HCI_OP_WRITE_AUTH_ENABLE:
2138 hci_cc_write_auth_enable(hdev, skb);
2139 break;
2140
2141 case HCI_OP_WRITE_ENCRYPT_MODE:
2142 hci_cc_write_encrypt_mode(hdev, skb);
2143 break;
2144
2145 case HCI_OP_WRITE_SCAN_ENABLE:
2146 hci_cc_write_scan_enable(hdev, skb);
2147 break;
2148
2149 case HCI_OP_READ_CLASS_OF_DEV:
2150 hci_cc_read_class_of_dev(hdev, skb);
2151 break;
2152
2153 case HCI_OP_WRITE_CLASS_OF_DEV:
2154 hci_cc_write_class_of_dev(hdev, skb);
2155 break;
2156
2157 case HCI_OP_READ_VOICE_SETTING:
2158 hci_cc_read_voice_setting(hdev, skb);
2159 break;
2160
2161 case HCI_OP_WRITE_VOICE_SETTING:
2162 hci_cc_write_voice_setting(hdev, skb);
2163 break;
2164
Marcel Holtmann333140b2008-07-14 20:13:48 +02002165 case HCI_OP_WRITE_SSP_MODE:
2166 hci_cc_write_ssp_mode(hdev, skb);
2167 break;
2168
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002169 case HCI_OP_READ_LOCAL_VERSION:
2170 hci_cc_read_local_version(hdev, skb);
2171 break;
2172
2173 case HCI_OP_READ_LOCAL_COMMANDS:
2174 hci_cc_read_local_commands(hdev, skb);
2175 break;
2176
2177 case HCI_OP_READ_LOCAL_FEATURES:
2178 hci_cc_read_local_features(hdev, skb);
2179 break;
2180
Andre Guedes971e3a42011-06-30 19:20:52 -03002181 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2182 hci_cc_read_local_ext_features(hdev, skb);
2183 break;
2184
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002185 case HCI_OP_READ_BUFFER_SIZE:
2186 hci_cc_read_buffer_size(hdev, skb);
2187 break;
2188
2189 case HCI_OP_READ_BD_ADDR:
2190 hci_cc_read_bd_addr(hdev, skb);
2191 break;
2192
Johan Hedbergf332ec62013-03-15 17:07:11 -05002193 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2194 hci_cc_read_page_scan_activity(hdev, skb);
2195 break;
2196
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002197 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2198 hci_cc_write_page_scan_activity(hdev, skb);
2199 break;
2200
Johan Hedbergf332ec62013-03-15 17:07:11 -05002201 case HCI_OP_READ_PAGE_SCAN_TYPE:
2202 hci_cc_read_page_scan_type(hdev, skb);
2203 break;
2204
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002205 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2206 hci_cc_write_page_scan_type(hdev, skb);
2207 break;
2208
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002209 case HCI_OP_READ_DATA_BLOCK_SIZE:
2210 hci_cc_read_data_block_size(hdev, skb);
2211 break;
2212
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002213 case HCI_OP_READ_FLOW_CONTROL_MODE:
2214 hci_cc_read_flow_control_mode(hdev, skb);
2215 break;
2216
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002217 case HCI_OP_READ_LOCAL_AMP_INFO:
2218 hci_cc_read_local_amp_info(hdev, skb);
2219 break;
2220
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002221 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2222 hci_cc_read_local_amp_assoc(hdev, skb);
2223 break;
2224
Johan Hedbergd5859e22011-01-25 01:19:58 +02002225 case HCI_OP_READ_INQ_RSP_TX_POWER:
2226 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2227 break;
2228
Johan Hedberg980e1a52011-01-22 06:10:07 +02002229 case HCI_OP_PIN_CODE_REPLY:
2230 hci_cc_pin_code_reply(hdev, skb);
2231 break;
2232
2233 case HCI_OP_PIN_CODE_NEG_REPLY:
2234 hci_cc_pin_code_neg_reply(hdev, skb);
2235 break;
2236
Szymon Jancc35938b2011-03-22 13:12:21 +01002237 case HCI_OP_READ_LOCAL_OOB_DATA:
2238 hci_cc_read_local_oob_data_reply(hdev, skb);
2239 break;
2240
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002241 case HCI_OP_LE_READ_BUFFER_SIZE:
2242 hci_cc_le_read_buffer_size(hdev, skb);
2243 break;
2244
Johan Hedberg60e77322013-01-22 14:01:59 +02002245 case HCI_OP_LE_READ_LOCAL_FEATURES:
2246 hci_cc_le_read_local_features(hdev, skb);
2247 break;
2248
Johan Hedberg8fa19092012-10-19 20:57:49 +03002249 case HCI_OP_LE_READ_ADV_TX_POWER:
2250 hci_cc_le_read_adv_tx_power(hdev, skb);
2251 break;
2252
Johan Hedberga5c29682011-02-19 12:05:57 -03002253 case HCI_OP_USER_CONFIRM_REPLY:
2254 hci_cc_user_confirm_reply(hdev, skb);
2255 break;
2256
2257 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2258 hci_cc_user_confirm_neg_reply(hdev, skb);
2259 break;
2260
Brian Gix1143d452011-11-23 08:28:34 -08002261 case HCI_OP_USER_PASSKEY_REPLY:
2262 hci_cc_user_passkey_reply(hdev, skb);
2263 break;
2264
2265 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2266 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002267 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002268
2269 case HCI_OP_LE_SET_SCAN_PARAM:
2270 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002271 break;
2272
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002273 case HCI_OP_LE_SET_ADV_ENABLE:
2274 hci_cc_le_set_adv_enable(hdev, skb);
2275 break;
2276
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002277 case HCI_OP_LE_SET_SCAN_ENABLE:
2278 hci_cc_le_set_scan_enable(hdev, skb);
2279 break;
2280
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002281 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2282 hci_cc_le_read_white_list_size(hdev, skb);
2283 break;
2284
Johan Hedberg9b008c02013-01-22 14:02:01 +02002285 case HCI_OP_LE_READ_SUPPORTED_STATES:
2286 hci_cc_le_read_supported_states(hdev, skb);
2287 break;
2288
Andre Guedesf9b49302011-06-30 19:20:53 -03002289 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2290 hci_cc_write_le_host_supported(hdev, skb);
2291 break;
2292
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002293 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2294 hci_cc_write_remote_amp_assoc(hdev, skb);
2295 break;
2296
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002297 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002298 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002299 break;
2300 }
2301
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002302 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002303 del_timer(&hdev->cmd_timer);
2304
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002305 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002306
Szymon Jancdbccd792012-12-11 08:51:19 +01002307 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002308 atomic_set(&hdev->cmd_cnt, 1);
2309 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002310 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002311 }
2312}
2313
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002314static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002315{
2316 struct hci_ev_cmd_status *ev = (void *) skb->data;
2317 __u16 opcode;
2318
2319 skb_pull(skb, sizeof(*ev));
2320
2321 opcode = __le16_to_cpu(ev->opcode);
2322
2323 switch (opcode) {
2324 case HCI_OP_INQUIRY:
2325 hci_cs_inquiry(hdev, ev->status);
2326 break;
2327
2328 case HCI_OP_CREATE_CONN:
2329 hci_cs_create_conn(hdev, ev->status);
2330 break;
2331
2332 case HCI_OP_ADD_SCO:
2333 hci_cs_add_sco(hdev, ev->status);
2334 break;
2335
Marcel Holtmannf8558552008-07-14 20:13:49 +02002336 case HCI_OP_AUTH_REQUESTED:
2337 hci_cs_auth_requested(hdev, ev->status);
2338 break;
2339
2340 case HCI_OP_SET_CONN_ENCRYPT:
2341 hci_cs_set_conn_encrypt(hdev, ev->status);
2342 break;
2343
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002344 case HCI_OP_REMOTE_NAME_REQ:
2345 hci_cs_remote_name_req(hdev, ev->status);
2346 break;
2347
Marcel Holtmann769be972008-07-14 20:13:49 +02002348 case HCI_OP_READ_REMOTE_FEATURES:
2349 hci_cs_read_remote_features(hdev, ev->status);
2350 break;
2351
2352 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2353 hci_cs_read_remote_ext_features(hdev, ev->status);
2354 break;
2355
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002356 case HCI_OP_SETUP_SYNC_CONN:
2357 hci_cs_setup_sync_conn(hdev, ev->status);
2358 break;
2359
2360 case HCI_OP_SNIFF_MODE:
2361 hci_cs_sniff_mode(hdev, ev->status);
2362 break;
2363
2364 case HCI_OP_EXIT_SNIFF_MODE:
2365 hci_cs_exit_sniff_mode(hdev, ev->status);
2366 break;
2367
Johan Hedberg8962ee72011-01-20 12:40:27 +02002368 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002369 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002370 break;
2371
Ville Tervofcd89c02011-02-10 22:38:47 -03002372 case HCI_OP_LE_CREATE_CONN:
2373 hci_cs_le_create_conn(hdev, ev->status);
2374 break;
2375
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002376 case HCI_OP_CREATE_PHY_LINK:
2377 hci_cs_create_phylink(hdev, ev->status);
2378 break;
2379
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002380 case HCI_OP_ACCEPT_PHY_LINK:
2381 hci_cs_accept_phylink(hdev, ev->status);
2382 break;
2383
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002384 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002385 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002386 break;
2387 }
2388
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002389 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002390 del_timer(&hdev->cmd_timer);
2391
Johan Hedberg02350a72013-04-03 21:50:29 +03002392 if (ev->status ||
2393 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2394 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002395
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002396 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002397 atomic_set(&hdev->cmd_cnt, 1);
2398 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002399 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002400 }
2401}
2402
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002403static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002404{
2405 struct hci_ev_role_change *ev = (void *) skb->data;
2406 struct hci_conn *conn;
2407
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002408 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002409
2410 hci_dev_lock(hdev);
2411
2412 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2413 if (conn) {
2414 if (!ev->status) {
2415 if (ev->role)
2416 conn->link_mode &= ~HCI_LM_MASTER;
2417 else
2418 conn->link_mode |= HCI_LM_MASTER;
2419 }
2420
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002421 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002422
2423 hci_role_switch_cfm(conn, ev->status, ev->role);
2424 }
2425
2426 hci_dev_unlock(hdev);
2427}
2428
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002429static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002431 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002432 int i;
2433
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002434 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2435 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2436 return;
2437 }
2438
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002439 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002440 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441 BT_DBG("%s bad parameters", hdev->name);
2442 return;
2443 }
2444
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002445 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2446
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002447 for (i = 0; i < ev->num_hndl; i++) {
2448 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449 struct hci_conn *conn;
2450 __u16 handle, count;
2451
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002452 handle = __le16_to_cpu(info->handle);
2453 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002454
2455 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002456 if (!conn)
2457 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002459 conn->sent -= count;
2460
2461 switch (conn->type) {
2462 case ACL_LINK:
2463 hdev->acl_cnt += count;
2464 if (hdev->acl_cnt > hdev->acl_pkts)
2465 hdev->acl_cnt = hdev->acl_pkts;
2466 break;
2467
2468 case LE_LINK:
2469 if (hdev->le_pkts) {
2470 hdev->le_cnt += count;
2471 if (hdev->le_cnt > hdev->le_pkts)
2472 hdev->le_cnt = hdev->le_pkts;
2473 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002474 hdev->acl_cnt += count;
2475 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002476 hdev->acl_cnt = hdev->acl_pkts;
2477 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002478 break;
2479
2480 case SCO_LINK:
2481 hdev->sco_cnt += count;
2482 if (hdev->sco_cnt > hdev->sco_pkts)
2483 hdev->sco_cnt = hdev->sco_pkts;
2484 break;
2485
2486 default:
2487 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2488 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002489 }
2490 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002491
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002492 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002493}
2494
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002495static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2496 __u16 handle)
2497{
2498 struct hci_chan *chan;
2499
2500 switch (hdev->dev_type) {
2501 case HCI_BREDR:
2502 return hci_conn_hash_lookup_handle(hdev, handle);
2503 case HCI_AMP:
2504 chan = hci_chan_lookup_handle(hdev, handle);
2505 if (chan)
2506 return chan->conn;
2507 break;
2508 default:
2509 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2510 break;
2511 }
2512
2513 return NULL;
2514}
2515
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002516static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002517{
2518 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2519 int i;
2520
2521 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2522 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2523 return;
2524 }
2525
2526 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002527 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002528 BT_DBG("%s bad parameters", hdev->name);
2529 return;
2530 }
2531
2532 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002533 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002534
2535 for (i = 0; i < ev->num_hndl; i++) {
2536 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002537 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002538 __u16 handle, block_count;
2539
2540 handle = __le16_to_cpu(info->handle);
2541 block_count = __le16_to_cpu(info->blocks);
2542
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002543 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002544 if (!conn)
2545 continue;
2546
2547 conn->sent -= block_count;
2548
2549 switch (conn->type) {
2550 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002551 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002552 hdev->block_cnt += block_count;
2553 if (hdev->block_cnt > hdev->num_blocks)
2554 hdev->block_cnt = hdev->num_blocks;
2555 break;
2556
2557 default:
2558 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2559 break;
2560 }
2561 }
2562
2563 queue_work(hdev->workqueue, &hdev->tx_work);
2564}
2565
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002566static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002568 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002569 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002571 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002572
2573 hci_dev_lock(hdev);
2574
Marcel Holtmann04837f62006-07-03 10:02:33 +02002575 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2576 if (conn) {
2577 conn->mode = ev->mode;
2578 conn->interval = __le16_to_cpu(ev->interval);
2579
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002580 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2581 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002582 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002583 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002584 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002585 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002586 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002587
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002588 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002589 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002590 }
2591
2592 hci_dev_unlock(hdev);
2593}
2594
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002595static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002597 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2598 struct hci_conn *conn;
2599
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002600 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002601
2602 hci_dev_lock(hdev);
2603
2604 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002605 if (!conn)
2606 goto unlock;
2607
2608 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002609 hci_conn_hold(conn);
2610 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002611 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002612 }
2613
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002614 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002615 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002616 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002617 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002618 u8 secure;
2619
2620 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2621 secure = 1;
2622 else
2623 secure = 0;
2624
Johan Hedberg744cf192011-11-08 20:40:14 +02002625 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002626 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002627
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002628unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002629 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630}
2631
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002632static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002634 struct hci_ev_link_key_req *ev = (void *) skb->data;
2635 struct hci_cp_link_key_reply cp;
2636 struct hci_conn *conn;
2637 struct link_key *key;
2638
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002639 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002640
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002641 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002642 return;
2643
2644 hci_dev_lock(hdev);
2645
2646 key = hci_find_link_key(hdev, &ev->bdaddr);
2647 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002648 BT_DBG("%s link key not found for %pMR", hdev->name,
2649 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002650 goto not_found;
2651 }
2652
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002653 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2654 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002655
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002656 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002657 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002658 BT_DBG("%s ignoring debug key", hdev->name);
2659 goto not_found;
2660 }
2661
2662 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002663 if (conn) {
2664 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002665 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002666 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2667 goto not_found;
2668 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002669
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002670 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002671 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002672 BT_DBG("%s ignoring key unauthenticated for high security",
2673 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002674 goto not_found;
2675 }
2676
2677 conn->key_type = key->type;
2678 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002679 }
2680
2681 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002682 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002683
2684 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2685
2686 hci_dev_unlock(hdev);
2687
2688 return;
2689
2690not_found:
2691 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2692 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002693}
2694
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002695static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002697 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2698 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002699 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002700
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002701 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002702
2703 hci_dev_lock(hdev);
2704
2705 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2706 if (conn) {
2707 hci_conn_hold(conn);
2708 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002709 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002710
2711 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2712 conn->key_type = ev->key_type;
2713
David Herrmann76a68ba2013-04-06 20:28:37 +02002714 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002715 }
2716
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002717 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002718 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002719 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002720
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002721 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002722}
2723
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002724static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002725{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002726 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002727 struct hci_conn *conn;
2728
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002729 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002730
2731 hci_dev_lock(hdev);
2732
2733 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002734 if (conn && !ev->status) {
2735 struct inquiry_entry *ie;
2736
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002737 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2738 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002739 ie->data.clock_offset = ev->clock_offset;
2740 ie->timestamp = jiffies;
2741 }
2742 }
2743
2744 hci_dev_unlock(hdev);
2745}
2746
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002747static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002748{
2749 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2750 struct hci_conn *conn;
2751
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002752 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002753
2754 hci_dev_lock(hdev);
2755
2756 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2757 if (conn && !ev->status)
2758 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2759
2760 hci_dev_unlock(hdev);
2761}
2762
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002763static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002764{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002765 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002766 struct inquiry_entry *ie;
2767
2768 BT_DBG("%s", hdev->name);
2769
2770 hci_dev_lock(hdev);
2771
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002772 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2773 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002774 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2775 ie->timestamp = jiffies;
2776 }
2777
2778 hci_dev_unlock(hdev);
2779}
2780
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002781static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2782 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002783{
2784 struct inquiry_data data;
2785 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002786 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002787
2788 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2789
2790 if (!num_rsp)
2791 return;
2792
Andre Guedes1519cc12012-03-21 00:03:38 -03002793 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2794 return;
2795
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002796 hci_dev_lock(hdev);
2797
2798 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002799 struct inquiry_info_with_rssi_and_pscan_mode *info;
2800 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002801
Johan Hedberge17acd42011-03-30 23:57:16 +03002802 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002803 bacpy(&data.bdaddr, &info->bdaddr);
2804 data.pscan_rep_mode = info->pscan_rep_mode;
2805 data.pscan_period_mode = info->pscan_period_mode;
2806 data.pscan_mode = info->pscan_mode;
2807 memcpy(data.dev_class, info->dev_class, 3);
2808 data.clock_offset = info->clock_offset;
2809 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002810 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002811
2812 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002813 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002814 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002815 info->dev_class, info->rssi,
2816 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002817 }
2818 } else {
2819 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2820
Johan Hedberge17acd42011-03-30 23:57:16 +03002821 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002822 bacpy(&data.bdaddr, &info->bdaddr);
2823 data.pscan_rep_mode = info->pscan_rep_mode;
2824 data.pscan_period_mode = info->pscan_period_mode;
2825 data.pscan_mode = 0x00;
2826 memcpy(data.dev_class, info->dev_class, 3);
2827 data.clock_offset = info->clock_offset;
2828 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002829 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002830 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002831 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002832 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002833 info->dev_class, info->rssi,
2834 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002835 }
2836 }
2837
2838 hci_dev_unlock(hdev);
2839}
2840
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002841static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2842 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002843{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002844 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2845 struct hci_conn *conn;
2846
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002847 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002848
Marcel Holtmann41a96212008-07-14 20:13:48 +02002849 hci_dev_lock(hdev);
2850
2851 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002852 if (!conn)
2853 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002854
Johan Hedbergcad718e2013-04-17 15:00:51 +03002855 if (ev->page < HCI_MAX_PAGES)
2856 memcpy(conn->features[ev->page], ev->features, 8);
2857
Johan Hedbergccd556f2010-11-10 17:11:51 +02002858 if (!ev->status && ev->page == 0x01) {
2859 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002860
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002861 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2862 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002863 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002864
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302865 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002866 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302867 } else {
2868 /* It is mandatory by the Bluetooth specification that
2869 * Extended Inquiry Results are only used when Secure
2870 * Simple Pairing is enabled, but some devices violate
2871 * this.
2872 *
2873 * To make these devices work, the internal SSP
2874 * enabled flag needs to be cleared if the remote host
2875 * features do not indicate SSP support */
2876 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2877 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002878 }
2879
Johan Hedbergccd556f2010-11-10 17:11:51 +02002880 if (conn->state != BT_CONFIG)
2881 goto unlock;
2882
Johan Hedberg671267b2012-05-12 16:11:50 -03002883 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002884 struct hci_cp_remote_name_req cp;
2885 memset(&cp, 0, sizeof(cp));
2886 bacpy(&cp.bdaddr, &conn->dst);
2887 cp.pscan_rep_mode = 0x02;
2888 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002889 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2890 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002891 conn->dst_type, 0, NULL, 0,
2892 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002893
Johan Hedberg127178d2010-11-18 22:22:29 +02002894 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002895 conn->state = BT_CONNECTED;
2896 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002897 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002898 }
2899
2900unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002901 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002902}
2903
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002904static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2905 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002906{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002907 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2908 struct hci_conn *conn;
2909
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002910 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002911
2912 hci_dev_lock(hdev);
2913
2914 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002915 if (!conn) {
2916 if (ev->link_type == ESCO_LINK)
2917 goto unlock;
2918
2919 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2920 if (!conn)
2921 goto unlock;
2922
2923 conn->type = SCO_LINK;
2924 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002925
Marcel Holtmann732547f2009-04-19 19:14:14 +02002926 switch (ev->status) {
2927 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002928 conn->handle = __le16_to_cpu(ev->handle);
2929 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002930
2931 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002932 break;
2933
Stephen Coe705e5712010-02-16 11:29:44 -05002934 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002935 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002936 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002937 case 0x1f: /* Unspecified error */
2938 if (conn->out && conn->attempt < 2) {
2939 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2940 (hdev->esco_type & EDR_ESCO_MASK);
2941 hci_setup_sync(conn, conn->link->handle);
2942 goto unlock;
2943 }
2944 /* fall through */
2945
2946 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002947 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002948 break;
2949 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002950
2951 hci_proto_connect_cfm(conn, ev->status);
2952 if (ev->status)
2953 hci_conn_del(conn);
2954
2955unlock:
2956 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002957}
2958
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002959static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2960 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002961{
2962 struct inquiry_data data;
2963 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2964 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302965 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002966
2967 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2968
2969 if (!num_rsp)
2970 return;
2971
Andre Guedes1519cc12012-03-21 00:03:38 -03002972 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2973 return;
2974
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002975 hci_dev_lock(hdev);
2976
Johan Hedberge17acd42011-03-30 23:57:16 +03002977 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002978 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002979
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002980 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002981 data.pscan_rep_mode = info->pscan_rep_mode;
2982 data.pscan_period_mode = info->pscan_period_mode;
2983 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002984 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002985 data.clock_offset = info->clock_offset;
2986 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002987 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002988
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002989 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002990 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002991 sizeof(info->data),
2992 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002993 else
2994 name_known = true;
2995
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002996 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002997 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302998 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02002999 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003000 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303001 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003002 }
3003
3004 hci_dev_unlock(hdev);
3005}
3006
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003007static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3008 struct sk_buff *skb)
3009{
3010 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3011 struct hci_conn *conn;
3012
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003013 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003014 __le16_to_cpu(ev->handle));
3015
3016 hci_dev_lock(hdev);
3017
3018 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3019 if (!conn)
3020 goto unlock;
3021
3022 if (!ev->status)
3023 conn->sec_level = conn->pending_sec_level;
3024
3025 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3026
3027 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003028 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003029 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003030 goto unlock;
3031 }
3032
3033 if (conn->state == BT_CONFIG) {
3034 if (!ev->status)
3035 conn->state = BT_CONNECTED;
3036
3037 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003038 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003039 } else {
3040 hci_auth_cfm(conn, ev->status);
3041
3042 hci_conn_hold(conn);
3043 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003044 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003045 }
3046
3047unlock:
3048 hci_dev_unlock(hdev);
3049}
3050
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003051static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003052{
3053 /* If remote requests dedicated bonding follow that lead */
3054 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3055 /* If both remote and local IO capabilities allow MITM
3056 * protection then require it, otherwise don't */
3057 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3058 return 0x02;
3059 else
3060 return 0x03;
3061 }
3062
3063 /* If remote requests no-bonding follow that lead */
3064 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003065 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003066
3067 return conn->auth_type;
3068}
3069
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003070static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003071{
3072 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3073 struct hci_conn *conn;
3074
3075 BT_DBG("%s", hdev->name);
3076
3077 hci_dev_lock(hdev);
3078
3079 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003080 if (!conn)
3081 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003082
Johan Hedberg03b555e2011-01-04 15:40:05 +02003083 hci_conn_hold(conn);
3084
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003085 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003086 goto unlock;
3087
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003088 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003089 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003090 struct hci_cp_io_capability_reply cp;
3091
3092 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303093 /* Change the IO capability from KeyboardDisplay
3094 * to DisplayYesNo as it is not supported by BT spec. */
3095 cp.capability = (conn->io_capability == 0x04) ?
3096 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003097 conn->auth_type = hci_get_auth_req(conn);
3098 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003099
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003100 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3101 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003102 cp.oob_data = 0x01;
3103 else
3104 cp.oob_data = 0x00;
3105
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003106 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003107 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003108 } else {
3109 struct hci_cp_io_capability_neg_reply cp;
3110
3111 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003112 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003113
3114 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003115 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003116 }
3117
3118unlock:
3119 hci_dev_unlock(hdev);
3120}
3121
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003122static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003123{
3124 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3125 struct hci_conn *conn;
3126
3127 BT_DBG("%s", hdev->name);
3128
3129 hci_dev_lock(hdev);
3130
3131 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3132 if (!conn)
3133 goto unlock;
3134
Johan Hedberg03b555e2011-01-04 15:40:05 +02003135 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003136 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003137 if (ev->oob_data)
3138 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003139
3140unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003141 hci_dev_unlock(hdev);
3142}
3143
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003144static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3145 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003146{
3147 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003148 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003149 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003150
3151 BT_DBG("%s", hdev->name);
3152
3153 hci_dev_lock(hdev);
3154
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003155 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003156 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003157
Johan Hedberg7a828902011-04-28 11:28:53 -07003158 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3159 if (!conn)
3160 goto unlock;
3161
3162 loc_mitm = (conn->auth_type & 0x01);
3163 rem_mitm = (conn->remote_auth & 0x01);
3164
3165 /* If we require MITM but the remote device can't provide that
3166 * (it has NoInputNoOutput) then reject the confirmation
3167 * request. The only exception is when we're dedicated bonding
3168 * initiators (connect_cfm_cb set) since then we always have the MITM
3169 * bit set. */
3170 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3171 BT_DBG("Rejecting request: remote device can't provide MITM");
3172 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003173 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003174 goto unlock;
3175 }
3176
3177 /* If no side requires MITM protection; auto-accept */
3178 if ((!loc_mitm || conn->remote_cap == 0x03) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003179 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003180
3181 /* If we're not the initiators request authorization to
3182 * proceed from user space (mgmt_user_confirm with
3183 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003184 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003185 BT_DBG("Confirming auto-accept as acceptor");
3186 confirm_hint = 1;
3187 goto confirm;
3188 }
3189
Johan Hedberg9f616562011-04-28 11:28:54 -07003190 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003191 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003192
3193 if (hdev->auto_accept_delay > 0) {
3194 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3195 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3196 goto unlock;
3197 }
3198
Johan Hedberg7a828902011-04-28 11:28:53 -07003199 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003200 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003201 goto unlock;
3202 }
3203
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003204confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003205 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003206 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003207
3208unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003209 hci_dev_unlock(hdev);
3210}
3211
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003212static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3213 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003214{
3215 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3216
3217 BT_DBG("%s", hdev->name);
3218
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003219 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003220 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003221}
3222
Johan Hedberg92a25252012-09-06 18:39:26 +03003223static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3224 struct sk_buff *skb)
3225{
3226 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3227 struct hci_conn *conn;
3228
3229 BT_DBG("%s", hdev->name);
3230
3231 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3232 if (!conn)
3233 return;
3234
3235 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3236 conn->passkey_entered = 0;
3237
3238 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3239 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3240 conn->dst_type, conn->passkey_notify,
3241 conn->passkey_entered);
3242}
3243
3244static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3245{
3246 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3247 struct hci_conn *conn;
3248
3249 BT_DBG("%s", hdev->name);
3250
3251 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3252 if (!conn)
3253 return;
3254
3255 switch (ev->type) {
3256 case HCI_KEYPRESS_STARTED:
3257 conn->passkey_entered = 0;
3258 return;
3259
3260 case HCI_KEYPRESS_ENTERED:
3261 conn->passkey_entered++;
3262 break;
3263
3264 case HCI_KEYPRESS_ERASED:
3265 conn->passkey_entered--;
3266 break;
3267
3268 case HCI_KEYPRESS_CLEARED:
3269 conn->passkey_entered = 0;
3270 break;
3271
3272 case HCI_KEYPRESS_COMPLETED:
3273 return;
3274 }
3275
3276 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3277 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3278 conn->dst_type, conn->passkey_notify,
3279 conn->passkey_entered);
3280}
3281
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003282static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3283 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003284{
3285 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3286 struct hci_conn *conn;
3287
3288 BT_DBG("%s", hdev->name);
3289
3290 hci_dev_lock(hdev);
3291
3292 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003293 if (!conn)
3294 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003295
Johan Hedberg2a611692011-02-19 12:06:00 -03003296 /* To avoid duplicate auth_failed events to user space we check
3297 * the HCI_CONN_AUTH_PEND flag which will be set if we
3298 * initiated the authentication. A traditional auth_complete
3299 * event gets always produced as initiator and is also mapped to
3300 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003301 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003302 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003303 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003304
David Herrmann76a68ba2013-04-06 20:28:37 +02003305 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003306
3307unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003308 hci_dev_unlock(hdev);
3309}
3310
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003311static void hci_remote_host_features_evt(struct hci_dev *hdev,
3312 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003313{
3314 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3315 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003316 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003317
3318 BT_DBG("%s", hdev->name);
3319
3320 hci_dev_lock(hdev);
3321
Johan Hedbergcad718e2013-04-17 15:00:51 +03003322 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3323 if (conn)
3324 memcpy(conn->features[1], ev->features, 8);
3325
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003326 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3327 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003328 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003329
3330 hci_dev_unlock(hdev);
3331}
3332
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003333static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3334 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003335{
3336 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3337 struct oob_data *data;
3338
3339 BT_DBG("%s", hdev->name);
3340
3341 hci_dev_lock(hdev);
3342
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003343 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003344 goto unlock;
3345
Szymon Janc2763eda2011-03-22 13:12:22 +01003346 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3347 if (data) {
3348 struct hci_cp_remote_oob_data_reply cp;
3349
3350 bacpy(&cp.bdaddr, &ev->bdaddr);
3351 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3352 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3353
3354 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003355 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003356 } else {
3357 struct hci_cp_remote_oob_data_neg_reply cp;
3358
3359 bacpy(&cp.bdaddr, &ev->bdaddr);
3360 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003361 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003362 }
3363
Szymon Jance1ba1f12011-04-06 13:01:59 +02003364unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003365 hci_dev_unlock(hdev);
3366}
3367
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003368static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3369 struct sk_buff *skb)
3370{
3371 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3372 struct hci_conn *hcon, *bredr_hcon;
3373
3374 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3375 ev->status);
3376
3377 hci_dev_lock(hdev);
3378
3379 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3380 if (!hcon) {
3381 hci_dev_unlock(hdev);
3382 return;
3383 }
3384
3385 if (ev->status) {
3386 hci_conn_del(hcon);
3387 hci_dev_unlock(hdev);
3388 return;
3389 }
3390
3391 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3392
3393 hcon->state = BT_CONNECTED;
3394 bacpy(&hcon->dst, &bredr_hcon->dst);
3395
3396 hci_conn_hold(hcon);
3397 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003398 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003399
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003400 hci_conn_add_sysfs(hcon);
3401
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003402 amp_physical_cfm(bredr_hcon, hcon);
3403
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003404 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003405}
3406
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003407static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3408{
3409 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3410 struct hci_conn *hcon;
3411 struct hci_chan *hchan;
3412 struct amp_mgr *mgr;
3413
3414 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3415 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3416 ev->status);
3417
3418 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3419 if (!hcon)
3420 return;
3421
3422 /* Create AMP hchan */
3423 hchan = hci_chan_create(hcon);
3424 if (!hchan)
3425 return;
3426
3427 hchan->handle = le16_to_cpu(ev->handle);
3428
3429 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3430
3431 mgr = hcon->amp_mgr;
3432 if (mgr && mgr->bredr_chan) {
3433 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3434
3435 l2cap_chan_lock(bredr_chan);
3436
3437 bredr_chan->conn->mtu = hdev->block_mtu;
3438 l2cap_logical_cfm(bredr_chan, hchan, 0);
3439 hci_conn_hold(hcon);
3440
3441 l2cap_chan_unlock(bredr_chan);
3442 }
3443}
3444
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003445static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3446 struct sk_buff *skb)
3447{
3448 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3449 struct hci_chan *hchan;
3450
3451 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3452 le16_to_cpu(ev->handle), ev->status);
3453
3454 if (ev->status)
3455 return;
3456
3457 hci_dev_lock(hdev);
3458
3459 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3460 if (!hchan)
3461 goto unlock;
3462
3463 amp_destroy_logical_link(hchan, ev->reason);
3464
3465unlock:
3466 hci_dev_unlock(hdev);
3467}
3468
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003469static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3470 struct sk_buff *skb)
3471{
3472 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3473 struct hci_conn *hcon;
3474
3475 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3476
3477 if (ev->status)
3478 return;
3479
3480 hci_dev_lock(hdev);
3481
3482 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3483 if (hcon) {
3484 hcon->state = BT_CLOSED;
3485 hci_conn_del(hcon);
3486 }
3487
3488 hci_dev_unlock(hdev);
3489}
3490
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003491static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003492{
3493 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3494 struct hci_conn *conn;
3495
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003496 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003497
3498 hci_dev_lock(hdev);
3499
Andre Guedesb47a09b2012-07-27 15:10:15 -03003500 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003501 if (!conn) {
3502 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3503 if (!conn) {
3504 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003505 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003506 }
Andre Guedes29b79882011-05-31 14:20:54 -03003507
3508 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003509
3510 if (ev->role == LE_CONN_ROLE_MASTER) {
3511 conn->out = true;
3512 conn->link_mode |= HCI_LM_MASTER;
3513 }
Ville Tervob62f3282011-02-10 22:38:50 -03003514 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003515
Andre Guedescd17dec2012-07-27 15:10:16 -03003516 if (ev->status) {
3517 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3518 conn->dst_type, ev->status);
3519 hci_proto_connect_cfm(conn, ev->status);
3520 conn->state = BT_CLOSED;
3521 hci_conn_del(conn);
3522 goto unlock;
3523 }
3524
Johan Hedbergb644ba32012-01-17 21:48:47 +02003525 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3526 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003527 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003528
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003529 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003530 conn->handle = __le16_to_cpu(ev->handle);
3531 conn->state = BT_CONNECTED;
3532
Ville Tervofcd89c02011-02-10 22:38:47 -03003533 hci_conn_add_sysfs(conn);
3534
3535 hci_proto_connect_cfm(conn, ev->status);
3536
3537unlock:
3538 hci_dev_unlock(hdev);
3539}
3540
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003541static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003542{
Andre Guedese95beb42011-09-26 20:48:35 -03003543 u8 num_reports = skb->data[0];
3544 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003545 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003546
Andre Guedese95beb42011-09-26 20:48:35 -03003547 while (num_reports--) {
3548 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003549
Andre Guedes3c9e9192012-01-10 18:20:50 -03003550 rssi = ev->data[ev->length];
3551 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003552 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003553
Andre Guedese95beb42011-09-26 20:48:35 -03003554 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003555 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003556}
3557
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003558static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003559{
3560 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3561 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003562 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003563 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003564 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003565
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003566 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003567
3568 hci_dev_lock(hdev);
3569
3570 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003571 if (conn == NULL)
3572 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003573
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003574 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3575 if (ltk == NULL)
3576 goto not_found;
3577
3578 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003579 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003580
3581 if (ltk->authenticated)
3582 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003583
3584 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3585
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003586 if (ltk->type & HCI_SMP_STK) {
3587 list_del(&ltk->list);
3588 kfree(ltk);
3589 }
3590
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003591 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003592
3593 return;
3594
3595not_found:
3596 neg.handle = ev->handle;
3597 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3598 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003599}
3600
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003601static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003602{
3603 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3604
3605 skb_pull(skb, sizeof(*le_ev));
3606
3607 switch (le_ev->subevent) {
3608 case HCI_EV_LE_CONN_COMPLETE:
3609 hci_le_conn_complete_evt(hdev, skb);
3610 break;
3611
Andre Guedes9aa04c92011-05-26 16:23:51 -03003612 case HCI_EV_LE_ADVERTISING_REPORT:
3613 hci_le_adv_report_evt(hdev, skb);
3614 break;
3615
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003616 case HCI_EV_LE_LTK_REQ:
3617 hci_le_ltk_request_evt(hdev, skb);
3618 break;
3619
Ville Tervofcd89c02011-02-10 22:38:47 -03003620 default:
3621 break;
3622 }
3623}
3624
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003625static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3626{
3627 struct hci_ev_channel_selected *ev = (void *) skb->data;
3628 struct hci_conn *hcon;
3629
3630 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3631
3632 skb_pull(skb, sizeof(*ev));
3633
3634 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3635 if (!hcon)
3636 return;
3637
3638 amp_read_loc_assoc_final_data(hdev, hcon);
3639}
3640
Linus Torvalds1da177e2005-04-16 15:20:36 -07003641void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3642{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003643 struct hci_event_hdr *hdr = (void *) skb->data;
3644 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003646 hci_dev_lock(hdev);
3647
3648 /* Received events are (currently) only needed when a request is
3649 * ongoing so avoid unnecessary memory allocation.
3650 */
3651 if (hdev->req_status == HCI_REQ_PEND) {
3652 kfree_skb(hdev->recv_evt);
3653 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3654 }
3655
3656 hci_dev_unlock(hdev);
3657
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3659
Johan Hedberg02350a72013-04-03 21:50:29 +03003660 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
3661 struct hci_command_hdr *hdr = (void *) hdev->sent_cmd->data;
3662 u16 opcode = __le16_to_cpu(hdr->opcode);
3663
3664 hci_req_cmd_complete(hdev, opcode, 0);
3665 }
3666
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003667 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668 case HCI_EV_INQUIRY_COMPLETE:
3669 hci_inquiry_complete_evt(hdev, skb);
3670 break;
3671
3672 case HCI_EV_INQUIRY_RESULT:
3673 hci_inquiry_result_evt(hdev, skb);
3674 break;
3675
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003676 case HCI_EV_CONN_COMPLETE:
3677 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003678 break;
3679
Linus Torvalds1da177e2005-04-16 15:20:36 -07003680 case HCI_EV_CONN_REQUEST:
3681 hci_conn_request_evt(hdev, skb);
3682 break;
3683
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684 case HCI_EV_DISCONN_COMPLETE:
3685 hci_disconn_complete_evt(hdev, skb);
3686 break;
3687
Linus Torvalds1da177e2005-04-16 15:20:36 -07003688 case HCI_EV_AUTH_COMPLETE:
3689 hci_auth_complete_evt(hdev, skb);
3690 break;
3691
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003692 case HCI_EV_REMOTE_NAME:
3693 hci_remote_name_evt(hdev, skb);
3694 break;
3695
Linus Torvalds1da177e2005-04-16 15:20:36 -07003696 case HCI_EV_ENCRYPT_CHANGE:
3697 hci_encrypt_change_evt(hdev, skb);
3698 break;
3699
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003700 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3701 hci_change_link_key_complete_evt(hdev, skb);
3702 break;
3703
3704 case HCI_EV_REMOTE_FEATURES:
3705 hci_remote_features_evt(hdev, skb);
3706 break;
3707
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003708 case HCI_EV_CMD_COMPLETE:
3709 hci_cmd_complete_evt(hdev, skb);
3710 break;
3711
3712 case HCI_EV_CMD_STATUS:
3713 hci_cmd_status_evt(hdev, skb);
3714 break;
3715
3716 case HCI_EV_ROLE_CHANGE:
3717 hci_role_change_evt(hdev, skb);
3718 break;
3719
3720 case HCI_EV_NUM_COMP_PKTS:
3721 hci_num_comp_pkts_evt(hdev, skb);
3722 break;
3723
3724 case HCI_EV_MODE_CHANGE:
3725 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003726 break;
3727
3728 case HCI_EV_PIN_CODE_REQ:
3729 hci_pin_code_request_evt(hdev, skb);
3730 break;
3731
3732 case HCI_EV_LINK_KEY_REQ:
3733 hci_link_key_request_evt(hdev, skb);
3734 break;
3735
3736 case HCI_EV_LINK_KEY_NOTIFY:
3737 hci_link_key_notify_evt(hdev, skb);
3738 break;
3739
3740 case HCI_EV_CLOCK_OFFSET:
3741 hci_clock_offset_evt(hdev, skb);
3742 break;
3743
Marcel Holtmanna8746412008-07-14 20:13:46 +02003744 case HCI_EV_PKT_TYPE_CHANGE:
3745 hci_pkt_type_change_evt(hdev, skb);
3746 break;
3747
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003748 case HCI_EV_PSCAN_REP_MODE:
3749 hci_pscan_rep_mode_evt(hdev, skb);
3750 break;
3751
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003752 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3753 hci_inquiry_result_with_rssi_evt(hdev, skb);
3754 break;
3755
3756 case HCI_EV_REMOTE_EXT_FEATURES:
3757 hci_remote_ext_features_evt(hdev, skb);
3758 break;
3759
3760 case HCI_EV_SYNC_CONN_COMPLETE:
3761 hci_sync_conn_complete_evt(hdev, skb);
3762 break;
3763
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003764 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3765 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003766 break;
3767
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003768 case HCI_EV_KEY_REFRESH_COMPLETE:
3769 hci_key_refresh_complete_evt(hdev, skb);
3770 break;
3771
Marcel Holtmann04936842008-07-14 20:13:48 +02003772 case HCI_EV_IO_CAPA_REQUEST:
3773 hci_io_capa_request_evt(hdev, skb);
3774 break;
3775
Johan Hedberg03b555e2011-01-04 15:40:05 +02003776 case HCI_EV_IO_CAPA_REPLY:
3777 hci_io_capa_reply_evt(hdev, skb);
3778 break;
3779
Johan Hedberga5c29682011-02-19 12:05:57 -03003780 case HCI_EV_USER_CONFIRM_REQUEST:
3781 hci_user_confirm_request_evt(hdev, skb);
3782 break;
3783
Brian Gix1143d452011-11-23 08:28:34 -08003784 case HCI_EV_USER_PASSKEY_REQUEST:
3785 hci_user_passkey_request_evt(hdev, skb);
3786 break;
3787
Johan Hedberg92a25252012-09-06 18:39:26 +03003788 case HCI_EV_USER_PASSKEY_NOTIFY:
3789 hci_user_passkey_notify_evt(hdev, skb);
3790 break;
3791
3792 case HCI_EV_KEYPRESS_NOTIFY:
3793 hci_keypress_notify_evt(hdev, skb);
3794 break;
3795
Marcel Holtmann04936842008-07-14 20:13:48 +02003796 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3797 hci_simple_pair_complete_evt(hdev, skb);
3798 break;
3799
Marcel Holtmann41a96212008-07-14 20:13:48 +02003800 case HCI_EV_REMOTE_HOST_FEATURES:
3801 hci_remote_host_features_evt(hdev, skb);
3802 break;
3803
Ville Tervofcd89c02011-02-10 22:38:47 -03003804 case HCI_EV_LE_META:
3805 hci_le_meta_evt(hdev, skb);
3806 break;
3807
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003808 case HCI_EV_CHANNEL_SELECTED:
3809 hci_chan_selected_evt(hdev, skb);
3810 break;
3811
Szymon Janc2763eda2011-03-22 13:12:22 +01003812 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3813 hci_remote_oob_data_request_evt(hdev, skb);
3814 break;
3815
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003816 case HCI_EV_PHY_LINK_COMPLETE:
3817 hci_phy_link_complete_evt(hdev, skb);
3818 break;
3819
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003820 case HCI_EV_LOGICAL_LINK_COMPLETE:
3821 hci_loglink_complete_evt(hdev, skb);
3822 break;
3823
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003824 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3825 hci_disconn_loglink_complete_evt(hdev, skb);
3826 break;
3827
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003828 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3829 hci_disconn_phylink_complete_evt(hdev, skb);
3830 break;
3831
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003832 case HCI_EV_NUM_COMP_BLOCKS:
3833 hci_num_comp_blocks_evt(hdev, skb);
3834 break;
3835
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003836 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003837 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003838 break;
3839 }
3840
3841 kfree_skb(skb);
3842 hdev->stat.evt_rx++;
3843}