blob: 09c65712e8cc8afbe6829d6f468c3b25472eb873 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <asm/unaligned.h>
28
29#include <net/bluetooth/bluetooth.h>
30#include <net/bluetooth/hci_core.h>
Mikel Astizf0d6a0e2012-08-09 09:52:30 +020031#include <net/bluetooth/mgmt.h>
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +030032#include <net/bluetooth/a2mp.h>
Andrei Emeltchenko903e4542012-09-27 17:26:09 +030033#include <net/bluetooth/amp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Linus Torvalds1da177e2005-04-16 15:20:36 -070035/* Handle HCI Event packets */
36
Marcel Holtmanna9de9242007-10-20 13:33:56 +020037static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070038{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020039 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030041 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Andre Guedese6d465c2011-11-09 17:14:26 -030043 if (status) {
44 hci_dev_lock(hdev);
45 mgmt_stop_discovery_failed(hdev, status);
46 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020047 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030048 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Andre Guedes89352e72011-11-04 14:16:53 -030050 clear_bit(HCI_INQUIRY, &hdev->flags);
51
Johan Hedberg56e5cb82011-11-08 20:40:16 +020052 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020053 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020054 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010055
Johan Hedberg23bb5762010-12-21 23:01:27 +020056 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010057
Marcel Holtmanna9de9242007-10-20 13:33:56 +020058 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070059}
60
Andre Guedes4d934832012-03-21 00:03:35 -030061static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
62{
63 __u8 status = *((__u8 *) skb->data);
64
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030065 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030066
67 if (status)
68 return;
69
70 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030071}
72
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020075 __u8 status = *((__u8 *) skb->data);
76
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030077 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020078
79 if (status)
80 return;
81
Andre Guedesae854a72012-03-21 00:03:36 -030082 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
83
Marcel Holtmanna9de9242007-10-20 13:33:56 +020084 hci_conn_check_pending(hdev);
85}
86
Gustavo Padovan807deac2012-05-17 00:36:24 -030087static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
88 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020089{
90 BT_DBG("%s", hdev->name);
91}
92
93static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
94{
95 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030098 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 if (rp->status)
101 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200103 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
106 if (conn) {
107 if (rp->role)
108 conn->link_mode &= ~HCI_LM_MASTER;
109 else
110 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200112
113 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114}
115
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200116static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
117{
118 struct hci_rp_read_link_policy *rp = (void *) skb->data;
119 struct hci_conn *conn;
120
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300121 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200122
123 if (rp->status)
124 return;
125
126 hci_dev_lock(hdev);
127
128 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
129 if (conn)
130 conn->link_policy = __le16_to_cpu(rp->policy);
131
132 hci_dev_unlock(hdev);
133}
134
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200137 struct hci_rp_write_link_policy *rp = (void *) skb->data;
138 struct hci_conn *conn;
139 void *sent;
140
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300141 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200142
143 if (rp->status)
144 return;
145
146 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
147 if (!sent)
148 return;
149
150 hci_dev_lock(hdev);
151
152 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200153 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700154 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200155
156 hci_dev_unlock(hdev);
157}
158
Gustavo Padovan807deac2012-05-17 00:36:24 -0300159static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
160 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200161{
162 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
163
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300164 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200165
166 if (rp->status)
167 return;
168
169 hdev->link_policy = __le16_to_cpu(rp->policy);
170}
171
Gustavo Padovan807deac2012-05-17 00:36:24 -0300172static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
173 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200174{
175 __u8 status = *((__u8 *) skb->data);
176 void *sent;
177
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300178 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200179
180 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
181 if (!sent)
182 return;
183
184 if (!status)
185 hdev->link_policy = get_unaligned_le16(sent);
186
Johan Hedberg23bb5762010-12-21 23:01:27 +0200187 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200188}
189
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200190static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
191{
192 __u8 status = *((__u8 *) skb->data);
193
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300194 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200195
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300196 clear_bit(HCI_RESET, &hdev->flags);
197
Johan Hedberg23bb5762010-12-21 23:01:27 +0200198 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300199
Johan Hedberga297e972012-02-21 17:55:47 +0200200 /* Reset all non-persistent flags */
Andre Guedesae854a72012-03-21 00:03:36 -0300201 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN) | BIT(HCI_PENDING_CLASS) |
202 BIT(HCI_PERIODIC_INQ));
Andre Guedes69775ff2012-02-23 16:50:05 +0200203
204 hdev->discovery.state = DISCOVERY_STOPPED;
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100205 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
206 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200207}
208
209static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
210{
211 __u8 status = *((__u8 *) skb->data);
212 void *sent;
213
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300214 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200215
216 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
217 if (!sent)
218 return;
219
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200220 hci_dev_lock(hdev);
221
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200222 if (test_bit(HCI_MGMT, &hdev->dev_flags))
223 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200224 else if (!status)
225 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200226
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200227 hci_dev_unlock(hdev);
Johan Hedberg3159d382012-02-24 13:47:56 +0200228
229 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200230}
231
232static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
233{
234 struct hci_rp_read_local_name *rp = (void *) skb->data;
235
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300236 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200237
238 if (rp->status)
239 return;
240
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200241 if (test_bit(HCI_SETUP, &hdev->dev_flags))
242 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200243}
244
245static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
246{
247 __u8 status = *((__u8 *) skb->data);
248 void *sent;
249
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300250 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200251
252 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
253 if (!sent)
254 return;
255
256 if (!status) {
257 __u8 param = *((__u8 *) sent);
258
259 if (param == AUTH_ENABLED)
260 set_bit(HCI_AUTH, &hdev->flags);
261 else
262 clear_bit(HCI_AUTH, &hdev->flags);
263 }
264
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200265 if (test_bit(HCI_MGMT, &hdev->dev_flags))
266 mgmt_auth_enable_complete(hdev, status);
267
Johan Hedberg23bb5762010-12-21 23:01:27 +0200268 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200269}
270
271static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
272{
273 __u8 status = *((__u8 *) skb->data);
274 void *sent;
275
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300276 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200277
278 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
279 if (!sent)
280 return;
281
282 if (!status) {
283 __u8 param = *((__u8 *) sent);
284
285 if (param)
286 set_bit(HCI_ENCRYPT, &hdev->flags);
287 else
288 clear_bit(HCI_ENCRYPT, &hdev->flags);
289 }
290
Johan Hedberg23bb5762010-12-21 23:01:27 +0200291 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200292}
293
294static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
295{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200296 __u8 param, status = *((__u8 *) skb->data);
297 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200298 void *sent;
299
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300300 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200301
302 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
303 if (!sent)
304 return;
305
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200306 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200307
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200308 hci_dev_lock(hdev);
309
Mikel Astizfa1bd912012-08-09 09:52:29 +0200310 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200311 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200312 hdev->discov_timeout = 0;
313 goto done;
314 }
315
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200316 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
317 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200318
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200319 if (param & SCAN_INQUIRY) {
320 set_bit(HCI_ISCAN, &hdev->flags);
321 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200322 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200323 if (hdev->discov_timeout > 0) {
324 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
325 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300326 to);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200327 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200328 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200329 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200330
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200331 if (param & SCAN_PAGE) {
332 set_bit(HCI_PSCAN, &hdev->flags);
333 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200334 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200335 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200336 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200337
338done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200339 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200340 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200341}
342
343static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
344{
345 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
346
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300347 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200348
349 if (rp->status)
350 return;
351
352 memcpy(hdev->dev_class, rp->dev_class, 3);
353
354 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300355 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200356}
357
358static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
359{
360 __u8 status = *((__u8 *) skb->data);
361 void *sent;
362
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300363 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200364
365 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
366 if (!sent)
367 return;
368
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100369 hci_dev_lock(hdev);
370
371 if (status == 0)
372 memcpy(hdev->dev_class, sent, 3);
373
374 if (test_bit(HCI_MGMT, &hdev->dev_flags))
375 mgmt_set_class_of_dev_complete(hdev, sent, status);
376
377 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200378}
379
380static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
381{
382 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300385 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200386
387 if (rp->status)
388 return;
389
390 setting = __le16_to_cpu(rp->voice_setting);
391
Marcel Holtmannf383f272008-07-14 20:13:47 +0200392 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200393 return;
394
395 hdev->voice_setting = setting;
396
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300397 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200398
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200399 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200400 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200401}
402
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300403static void hci_cc_write_voice_setting(struct hci_dev *hdev,
404 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200405{
406 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200407 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 void *sent;
409
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300410 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Marcel Holtmannf383f272008-07-14 20:13:47 +0200412 if (status)
413 return;
414
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200415 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
416 if (!sent)
417 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
Marcel Holtmannf383f272008-07-14 20:13:47 +0200419 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
Marcel Holtmannf383f272008-07-14 20:13:47 +0200421 if (hdev->voice_setting == setting)
422 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423
Marcel Holtmannf383f272008-07-14 20:13:47 +0200424 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300426 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200427
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200428 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200429 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430}
431
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200432static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200434 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300436 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437
Johan Hedberg23bb5762010-12-21 23:01:27 +0200438 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439}
440
Marcel Holtmann333140b2008-07-14 20:13:48 +0200441static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
442{
443 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300444 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200445
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300446 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200447
Marcel Holtmann333140b2008-07-14 20:13:48 +0200448 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
449 if (!sent)
450 return;
451
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300452 if (!status) {
453 if (sent->mode)
454 hdev->host_features[0] |= LMP_HOST_SSP;
455 else
456 hdev->host_features[0] &= ~LMP_HOST_SSP;
457 }
458
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200459 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300460 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200461 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300462 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200463 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
464 else
465 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
466 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200467}
468
Johan Hedbergd5859e22011-01-25 01:19:58 +0200469static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
470{
Johan Hedberg976eb202012-10-24 21:12:01 +0300471 if (lmp_ext_inq_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200472 return 2;
473
Johan Hedberg976eb202012-10-24 21:12:01 +0300474 if (lmp_inq_rssi_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200475 return 1;
476
477 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -0300478 hdev->lmp_subver == 0x0757)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200479 return 1;
480
481 if (hdev->manufacturer == 15) {
482 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
483 return 1;
484 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
485 return 1;
486 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
487 return 1;
488 }
489
490 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -0300491 hdev->lmp_subver == 0x1805)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200492 return 1;
493
494 return 0;
495}
496
497static void hci_setup_inquiry_mode(struct hci_dev *hdev)
498{
499 u8 mode;
500
501 mode = hci_get_inquiry_mode(hdev);
502
503 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
504}
505
506static void hci_setup_event_mask(struct hci_dev *hdev)
507{
508 /* The second byte is 0xff instead of 0x9f (two reserved bits
509 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
510 * command otherwise */
511 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
512
Ville Tervo6de6c182011-05-27 11:16:21 +0300513 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
514 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200515 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300516 return;
517
Johan Hedberge1171e82012-10-19 20:57:45 +0300518 if (lmp_bredr_capable(hdev)) {
519 events[4] |= 0x01; /* Flow Specification Complete */
520 events[4] |= 0x02; /* Inquiry Result with RSSI */
521 events[4] |= 0x04; /* Read Remote Extended Features Complete */
522 events[5] |= 0x08; /* Synchronous Connection Complete */
523 events[5] |= 0x10; /* Synchronous Connection Changed */
524 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200525
Johan Hedberg976eb202012-10-24 21:12:01 +0300526 if (lmp_inq_rssi_capable(hdev))
Johan Hedberga24299e2012-04-26 09:47:46 +0300527 events[4] |= 0x02; /* Inquiry Result with RSSI */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200528
Andre Guedes999dcd12012-07-24 15:03:52 -0300529 if (lmp_sniffsubr_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200530 events[5] |= 0x20; /* Sniff Subrating */
531
Johan Hedberg976eb202012-10-24 21:12:01 +0300532 if (lmp_pause_enc_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200533 events[5] |= 0x80; /* Encryption Key Refresh Complete */
534
Johan Hedberg976eb202012-10-24 21:12:01 +0300535 if (lmp_ext_inq_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200536 events[5] |= 0x40; /* Extended Inquiry Result */
537
Andre Guedesc58e8102012-07-24 15:03:53 -0300538 if (lmp_no_flush_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200539 events[7] |= 0x01; /* Enhanced Flush Complete */
540
Johan Hedberg976eb202012-10-24 21:12:01 +0300541 if (lmp_lsto_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200542 events[6] |= 0x80; /* Link Supervision Timeout Changed */
543
Andre Guedes9a1a1992012-07-24 15:03:48 -0300544 if (lmp_ssp_capable(hdev)) {
Johan Hedbergd5859e22011-01-25 01:19:58 +0200545 events[6] |= 0x01; /* IO Capability Request */
546 events[6] |= 0x02; /* IO Capability Response */
547 events[6] |= 0x04; /* User Confirmation Request */
548 events[6] |= 0x08; /* User Passkey Request */
549 events[6] |= 0x10; /* Remote OOB Data Request */
550 events[6] |= 0x20; /* Simple Pairing Complete */
551 events[7] |= 0x04; /* User Passkey Notification */
552 events[7] |= 0x08; /* Keypress Notification */
553 events[7] |= 0x10; /* Remote Host Supported
554 * Features Notification */
555 }
556
Andre Guedesc383ddc2012-07-24 15:03:47 -0300557 if (lmp_le_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200558 events[7] |= 0x20; /* LE Meta-Event */
559
560 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
Johan Hedberge36b04c2012-10-19 20:57:47 +0300561
562 if (lmp_le_capable(hdev)) {
563 memset(events, 0, sizeof(events));
564 events[0] = 0x1f;
565 hci_send_cmd(hdev, HCI_OP_LE_SET_EVENT_MASK,
566 sizeof(events), events);
567 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200568}
569
Gustavo Padovan4611dfa2012-10-24 11:18:41 -0200570static void bredr_setup(struct hci_dev *hdev)
Johan Hedberge1171e82012-10-19 20:57:45 +0300571{
572 struct hci_cp_delete_stored_link_key cp;
573 __le16 param;
574 __u8 flt_type;
575
576 /* Read Buffer Size (ACL mtu, max pkt, etc.) */
577 hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
578
579 /* Read Class of Device */
580 hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
581
582 /* Read Local Name */
583 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
584
585 /* Read Voice Setting */
586 hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
587
588 /* Clear Event Filters */
589 flt_type = HCI_FLT_CLEAR_ALL;
590 hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
591
592 /* Connection accept timeout ~20 secs */
593 param = __constant_cpu_to_le16(0x7d00);
594 hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
595
596 bacpy(&cp.bdaddr, BDADDR_ANY);
597 cp.delete_all = 1;
598 hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
599}
600
Gustavo Padovan4611dfa2012-10-24 11:18:41 -0200601static void le_setup(struct hci_dev *hdev)
Johan Hedberge1171e82012-10-19 20:57:45 +0300602{
603 /* Read LE Buffer Size */
604 hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
Johan Hedberg8fa19092012-10-19 20:57:49 +0300605
606 /* Read LE Advertising Channel TX Power */
607 hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
Johan Hedberge1171e82012-10-19 20:57:45 +0300608}
609
Johan Hedbergd5859e22011-01-25 01:19:58 +0200610static void hci_setup(struct hci_dev *hdev)
611{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200612 if (hdev->dev_type != HCI_BREDR)
613 return;
614
Johan Hedberge1171e82012-10-19 20:57:45 +0300615 /* Read BD Address */
616 hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
617
618 if (lmp_bredr_capable(hdev))
Gustavo Padovan4611dfa2012-10-24 11:18:41 -0200619 bredr_setup(hdev);
Johan Hedberge1171e82012-10-19 20:57:45 +0300620
621 if (lmp_le_capable(hdev))
Gustavo Padovan4611dfa2012-10-24 11:18:41 -0200622 le_setup(hdev);
Johan Hedberge1171e82012-10-19 20:57:45 +0300623
Johan Hedbergd5859e22011-01-25 01:19:58 +0200624 hci_setup_event_mask(hdev);
625
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200626 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200627 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
628
Gustavo Padovan6d3c7302012-05-24 03:36:37 -0300629 if (lmp_ssp_capable(hdev)) {
Johan Hedberg54d04db2012-02-22 15:47:48 +0200630 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
631 u8 mode = 0x01;
632 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300633 sizeof(mode), &mode);
Johan Hedberg54d04db2012-02-22 15:47:48 +0200634 } else {
635 struct hci_cp_write_eir cp;
636
637 memset(hdev->eir, 0, sizeof(hdev->eir));
638 memset(&cp, 0, sizeof(cp));
639
640 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
641 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200642 }
643
Johan Hedberg976eb202012-10-24 21:12:01 +0300644 if (lmp_inq_rssi_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200645 hci_setup_inquiry_mode(hdev);
646
Johan Hedberg976eb202012-10-24 21:12:01 +0300647 if (lmp_inq_tx_pwr_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200648 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300649
Johan Hedberg976eb202012-10-24 21:12:01 +0300650 if (lmp_ext_feat_capable(hdev)) {
Andre Guedes971e3a42011-06-30 19:20:52 -0300651 struct hci_cp_read_local_ext_features cp;
652
653 cp.page = 0x01;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300654 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp),
655 &cp);
Andre Guedes971e3a42011-06-30 19:20:52 -0300656 }
Andre Guedese6100a22011-06-30 19:20:54 -0300657
Johan Hedberg47990ea2012-02-22 11:58:37 +0200658 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
659 u8 enable = 1;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300660 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
661 &enable);
Johan Hedberg47990ea2012-02-22 11:58:37 +0200662 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200663}
664
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200665static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
666{
667 struct hci_rp_read_local_version *rp = (void *) skb->data;
668
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300669 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200670
671 if (rp->status)
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200672 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200673
674 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200675 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200676 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200677 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200678 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200679
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300680 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300681 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200682
683 if (test_bit(HCI_INIT, &hdev->flags))
684 hci_setup(hdev);
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200685
686done:
687 hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200688}
689
690static void hci_setup_link_policy(struct hci_dev *hdev)
691{
Andrei Emeltchenko035100c2012-03-12 15:59:32 +0200692 struct hci_cp_write_def_link_policy cp;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200693 u16 link_policy = 0;
694
Andre Guedes9f92ebf2012-07-24 15:03:50 -0300695 if (lmp_rswitch_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200696 link_policy |= HCI_LP_RSWITCH;
Johan Hedberg976eb202012-10-24 21:12:01 +0300697 if (lmp_hold_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200698 link_policy |= HCI_LP_HOLD;
Andre Guedes6eded102012-07-24 15:03:51 -0300699 if (lmp_sniff_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200700 link_policy |= HCI_LP_SNIFF;
Johan Hedberg976eb202012-10-24 21:12:01 +0300701 if (lmp_park_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200702 link_policy |= HCI_LP_PARK;
703
Andrei Emeltchenko035100c2012-03-12 15:59:32 +0200704 cp.policy = cpu_to_le16(link_policy);
705 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200706}
707
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300708static void hci_cc_read_local_commands(struct hci_dev *hdev,
709 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200710{
711 struct hci_rp_read_local_commands *rp = (void *) skb->data;
712
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300713 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200714
715 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200716 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200717
718 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200719
720 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
721 hci_setup_link_policy(hdev);
722
723done:
724 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200725}
726
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300727static void hci_cc_read_local_features(struct hci_dev *hdev,
728 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200729{
730 struct hci_rp_read_local_features *rp = (void *) skb->data;
731
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300732 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200733
734 if (rp->status)
735 return;
736
737 memcpy(hdev->features, rp->features, 8);
738
739 /* Adjust default settings according to features
740 * supported by device. */
741
742 if (hdev->features[0] & LMP_3SLOT)
743 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
744
745 if (hdev->features[0] & LMP_5SLOT)
746 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
747
748 if (hdev->features[1] & LMP_HV2) {
749 hdev->pkt_type |= (HCI_HV2);
750 hdev->esco_type |= (ESCO_HV2);
751 }
752
753 if (hdev->features[1] & LMP_HV3) {
754 hdev->pkt_type |= (HCI_HV3);
755 hdev->esco_type |= (ESCO_HV3);
756 }
757
Andre Guedes45db810f2012-07-24 15:03:49 -0300758 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200759 hdev->esco_type |= (ESCO_EV3);
760
761 if (hdev->features[4] & LMP_EV4)
762 hdev->esco_type |= (ESCO_EV4);
763
764 if (hdev->features[4] & LMP_EV5)
765 hdev->esco_type |= (ESCO_EV5);
766
Marcel Holtmannefc76882009-02-06 09:13:37 +0100767 if (hdev->features[5] & LMP_EDR_ESCO_2M)
768 hdev->esco_type |= (ESCO_2EV3);
769
770 if (hdev->features[5] & LMP_EDR_ESCO_3M)
771 hdev->esco_type |= (ESCO_3EV3);
772
773 if (hdev->features[5] & LMP_EDR_3S_ESCO)
774 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
775
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200776 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300777 hdev->features[0], hdev->features[1],
778 hdev->features[2], hdev->features[3],
779 hdev->features[4], hdev->features[5],
780 hdev->features[6], hdev->features[7]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200781}
782
Johan Hedberg8f984df2012-02-28 01:07:22 +0200783static void hci_set_le_support(struct hci_dev *hdev)
784{
785 struct hci_cp_write_le_host_supported cp;
786
787 memset(&cp, 0, sizeof(cp));
788
Marcel Holtmann9d428202012-05-03 07:12:31 +0200789 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
Johan Hedberg8f984df2012-02-28 01:07:22 +0200790 cp.le = 1;
Johan Hedberg976eb202012-10-24 21:12:01 +0300791 cp.simul = !!lmp_le_br_capable(hdev);
Johan Hedberg8f984df2012-02-28 01:07:22 +0200792 }
793
Johan Hedberg976eb202012-10-24 21:12:01 +0300794 if (cp.le != !!lmp_host_le_capable(hdev))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300795 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
796 &cp);
Johan Hedberg8f984df2012-02-28 01:07:22 +0200797}
798
Andre Guedes971e3a42011-06-30 19:20:52 -0300799static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300800 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300801{
802 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
803
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300804 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300805
806 if (rp->status)
Johan Hedberg8f984df2012-02-28 01:07:22 +0200807 goto done;
Andre Guedes971e3a42011-06-30 19:20:52 -0300808
Andre Guedesb5b32b62011-12-30 10:34:04 -0300809 switch (rp->page) {
810 case 0:
811 memcpy(hdev->features, rp->features, 8);
812 break;
813 case 1:
814 memcpy(hdev->host_features, rp->features, 8);
815 break;
816 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300817
Andre Guedesc383ddc2012-07-24 15:03:47 -0300818 if (test_bit(HCI_INIT, &hdev->flags) && lmp_le_capable(hdev))
Johan Hedberg8f984df2012-02-28 01:07:22 +0200819 hci_set_le_support(hdev);
820
821done:
Andre Guedes971e3a42011-06-30 19:20:52 -0300822 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
823}
824
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200825static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300826 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200827{
828 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
829
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300830 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200831
832 if (rp->status)
833 return;
834
835 hdev->flow_ctl_mode = rp->mode;
836
837 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
838}
839
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200840static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
841{
842 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
843
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300844 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200845
846 if (rp->status)
847 return;
848
849 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
850 hdev->sco_mtu = rp->sco_mtu;
851 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
852 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
853
854 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
855 hdev->sco_mtu = 64;
856 hdev->sco_pkts = 8;
857 }
858
859 hdev->acl_cnt = hdev->acl_pkts;
860 hdev->sco_cnt = hdev->sco_pkts;
861
Gustavo Padovan807deac2012-05-17 00:36:24 -0300862 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
863 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200864}
865
866static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
867{
868 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
869
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300870 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200871
872 if (!rp->status)
873 bacpy(&hdev->bdaddr, &rp->bdaddr);
874
Johan Hedberg23bb5762010-12-21 23:01:27 +0200875 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
876}
877
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200878static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300879 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200880{
881 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
882
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300883 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200884
885 if (rp->status)
886 return;
887
888 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
889 hdev->block_len = __le16_to_cpu(rp->block_len);
890 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
891
892 hdev->block_cnt = hdev->num_blocks;
893
894 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300895 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200896
897 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
898}
899
Johan Hedberg23bb5762010-12-21 23:01:27 +0200900static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
901{
902 __u8 status = *((__u8 *) skb->data);
903
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300904 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200905
906 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200907}
908
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300909static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300910 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300911{
912 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
913
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300914 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300915
916 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300917 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300918
919 hdev->amp_status = rp->amp_status;
920 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
921 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
922 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
923 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
924 hdev->amp_type = rp->amp_type;
925 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
926 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
927 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
928 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
929
930 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300931
932a2mp_rsp:
933 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300934}
935
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300936static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
937 struct sk_buff *skb)
938{
939 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
940 struct amp_assoc *assoc = &hdev->loc_assoc;
941 size_t rem_len, frag_len;
942
943 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
944
945 if (rp->status)
946 goto a2mp_rsp;
947
948 frag_len = skb->len - sizeof(*rp);
949 rem_len = __le16_to_cpu(rp->rem_len);
950
951 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300952 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300953
954 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
955 assoc->offset += frag_len;
956
957 /* Read other fragments */
958 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
959
960 return;
961 }
962
963 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
964 assoc->len = assoc->offset + rem_len;
965 assoc->offset = 0;
966
967a2mp_rsp:
968 /* Send A2MP Rsp when all fragments are received */
969 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300970 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300971}
972
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200973static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300974 struct sk_buff *skb)
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200975{
976 __u8 status = *((__u8 *) skb->data);
977
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300978 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200979
980 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
981}
982
Johan Hedbergd5859e22011-01-25 01:19:58 +0200983static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
984{
985 __u8 status = *((__u8 *) skb->data);
986
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300987 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200988
989 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
990}
991
992static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300993 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200994{
995 __u8 status = *((__u8 *) skb->data);
996
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300997 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200998
999 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
1000}
1001
1002static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001003 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +02001004{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -07001005 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +02001006
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001007 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +02001008
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -07001009 if (!rp->status)
1010 hdev->inq_tx_power = rp->tx_power;
1011
1012 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +02001013}
1014
1015static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
1016{
1017 __u8 status = *((__u8 *) skb->data);
1018
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001019 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedbergd5859e22011-01-25 01:19:58 +02001020
1021 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
1022}
1023
Johan Hedberg980e1a52011-01-22 06:10:07 +02001024static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
1025{
1026 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
1027 struct hci_cp_pin_code_reply *cp;
1028 struct hci_conn *conn;
1029
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001030 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +02001031
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001032 hci_dev_lock(hdev);
1033
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001034 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001035 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +02001036
Mikel Astizfa1bd912012-08-09 09:52:29 +02001037 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001038 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +02001039
1040 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
1041 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001042 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +02001043
1044 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1045 if (conn)
1046 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001047
1048unlock:
1049 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +02001050}
1051
1052static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1053{
1054 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
1055
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001056 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +02001057
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001058 hci_dev_lock(hdev);
1059
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001060 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001061 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001062 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001063
1064 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +02001065}
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001066
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001067static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
1068 struct sk_buff *skb)
1069{
1070 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
1071
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001072 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001073
1074 if (rp->status)
1075 return;
1076
1077 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
1078 hdev->le_pkts = rp->le_max_pkt;
1079
1080 hdev->le_cnt = hdev->le_pkts;
1081
1082 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
1083
1084 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
1085}
Johan Hedberg980e1a52011-01-22 06:10:07 +02001086
Johan Hedberg8fa19092012-10-19 20:57:49 +03001087static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
1088 struct sk_buff *skb)
1089{
1090 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
1091
1092 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1093
1094 if (!rp->status)
1095 hdev->adv_tx_power = rp->tx_power;
1096
1097 hci_req_complete(hdev, HCI_OP_LE_READ_ADV_TX_POWER, rp->status);
1098}
1099
Johan Hedberge36b04c2012-10-19 20:57:47 +03001100static void hci_cc_le_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
1101{
1102 __u8 status = *((__u8 *) skb->data);
1103
1104 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1105
1106 hci_req_complete(hdev, HCI_OP_LE_SET_EVENT_MASK, status);
1107}
1108
Johan Hedberga5c29682011-02-19 12:05:57 -03001109static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
1110{
1111 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1112
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001113 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -03001114
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001115 hci_dev_lock(hdev);
1116
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001117 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001118 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
1119 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001120
1121 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -03001122}
1123
1124static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001125 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03001126{
1127 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1128
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001129 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -03001130
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001131 hci_dev_lock(hdev);
1132
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001133 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001134 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001135 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001136
1137 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -03001138}
1139
Brian Gix1143d452011-11-23 08:28:34 -08001140static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
1141{
1142 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1143
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001144 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001145
1146 hci_dev_lock(hdev);
1147
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001148 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001149 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001150 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001151
1152 hci_dev_unlock(hdev);
1153}
1154
1155static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001156 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08001157{
1158 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1159
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001160 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001161
1162 hci_dev_lock(hdev);
1163
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001164 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001165 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001166 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001167
1168 hci_dev_unlock(hdev);
1169}
1170
Szymon Jancc35938b2011-03-22 13:12:21 +01001171static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001172 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +01001173{
1174 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1175
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001176 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +01001177
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001178 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001179 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001180 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001181 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001182}
1183
Andre Guedes07f7fa52011-12-02 21:13:31 +09001184static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1185{
1186 __u8 status = *((__u8 *) skb->data);
1187
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001188 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001189
1190 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001191
1192 if (status) {
1193 hci_dev_lock(hdev);
1194 mgmt_start_discovery_failed(hdev, status);
1195 hci_dev_unlock(hdev);
1196 return;
1197 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001198}
1199
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001200static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001201 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001202{
1203 struct hci_cp_le_set_scan_enable *cp;
1204 __u8 status = *((__u8 *) skb->data);
1205
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001206 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001207
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001208 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1209 if (!cp)
1210 return;
1211
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001212 switch (cp->enable) {
1213 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001214 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1215
Andre Guedes3fd24152012-02-03 17:48:01 -03001216 if (status) {
1217 hci_dev_lock(hdev);
1218 mgmt_start_discovery_failed(hdev, status);
1219 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001220 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001221 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001222
Andre Guedesd23264a2011-11-25 20:53:38 -03001223 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1224
Andre Guedesa8f13c82011-09-09 18:56:24 -03001225 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001226 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001227 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001228 break;
1229
1230 case LE_SCANNING_DISABLED:
Andre Guedesc9ecc482012-03-15 16:52:08 -03001231 if (status) {
1232 hci_dev_lock(hdev);
1233 mgmt_stop_discovery_failed(hdev, status);
1234 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001235 return;
Andre Guedesc9ecc482012-03-15 16:52:08 -03001236 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001237
Andre Guedesd23264a2011-11-25 20:53:38 -03001238 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1239
Andre Guedesbc3dd332012-03-06 19:37:06 -03001240 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
1241 hdev->discovery.state == DISCOVERY_FINDING) {
Andre Guedes5e0452c2012-02-17 20:39:38 -03001242 mgmt_interleaved_discovery(hdev);
1243 } else {
1244 hci_dev_lock(hdev);
1245 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1246 hci_dev_unlock(hdev);
1247 }
1248
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001249 break;
1250
1251 default:
1252 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1253 break;
Andre Guedes35815082011-05-26 16:23:53 -03001254 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001255}
1256
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001257static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1258{
1259 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1260
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001261 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001262
1263 if (rp->status)
1264 return;
1265
1266 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1267}
1268
1269static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1270{
1271 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1272
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001273 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001274
1275 if (rp->status)
1276 return;
1277
1278 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1279}
1280
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001281static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1282 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001283{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001284 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001285 __u8 status = *((__u8 *) skb->data);
1286
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001287 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001288
Johan Hedberg06199cf2012-02-22 16:37:11 +02001289 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001290 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001291 return;
1292
Johan Hedberg8f984df2012-02-28 01:07:22 +02001293 if (!status) {
1294 if (sent->le)
1295 hdev->host_features[0] |= LMP_HOST_LE;
1296 else
1297 hdev->host_features[0] &= ~LMP_HOST_LE;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001298
1299 if (sent->simul)
1300 hdev->host_features[0] |= LMP_HOST_LE_BREDR;
1301 else
1302 hdev->host_features[0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001303 }
1304
1305 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001306 !test_bit(HCI_INIT, &hdev->flags))
Johan Hedberg8f984df2012-02-28 01:07:22 +02001307 mgmt_le_enable_complete(hdev, sent->le, status);
1308
1309 hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001310}
1311
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001312static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1313 struct sk_buff *skb)
1314{
1315 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1316
1317 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1318 hdev->name, rp->status, rp->phy_handle);
1319
1320 if (rp->status)
1321 return;
1322
1323 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1324}
1325
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001326static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001327{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001328 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001329
1330 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001331 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001332 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001333 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001334 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001335 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001336 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001337 return;
1338 }
1339
Andre Guedes89352e72011-11-04 14:16:53 -03001340 set_bit(HCI_INQUIRY, &hdev->flags);
1341
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001342 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001343 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001344 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001345}
1346
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001347static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001349 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001352 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001353
1354 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 if (!cp)
1356 return;
1357
1358 hci_dev_lock(hdev);
1359
1360 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1361
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001362 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363
1364 if (status) {
1365 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001366 if (status != 0x0c || conn->attempt > 2) {
1367 conn->state = BT_CLOSED;
1368 hci_proto_connect_cfm(conn, status);
1369 hci_conn_del(conn);
1370 } else
1371 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 }
1373 } else {
1374 if (!conn) {
1375 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1376 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001377 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378 conn->link_mode |= HCI_LM_MASTER;
1379 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001380 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 }
1382 }
1383
1384 hci_dev_unlock(hdev);
1385}
1386
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001387static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001389 struct hci_cp_add_sco *cp;
1390 struct hci_conn *acl, *sco;
1391 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001393 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001394
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001395 if (!status)
1396 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001398 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1399 if (!cp)
1400 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001402 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001404 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001405
1406 hci_dev_lock(hdev);
1407
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001408 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001409 if (acl) {
1410 sco = acl->link;
1411 if (sco) {
1412 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001413
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001414 hci_proto_connect_cfm(sco, status);
1415 hci_conn_del(sco);
1416 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001417 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001418
1419 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420}
1421
Marcel Holtmannf8558552008-07-14 20:13:49 +02001422static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1423{
1424 struct hci_cp_auth_requested *cp;
1425 struct hci_conn *conn;
1426
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001427 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001428
1429 if (!status)
1430 return;
1431
1432 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1433 if (!cp)
1434 return;
1435
1436 hci_dev_lock(hdev);
1437
1438 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1439 if (conn) {
1440 if (conn->state == BT_CONFIG) {
1441 hci_proto_connect_cfm(conn, status);
1442 hci_conn_put(conn);
1443 }
1444 }
1445
1446 hci_dev_unlock(hdev);
1447}
1448
1449static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1450{
1451 struct hci_cp_set_conn_encrypt *cp;
1452 struct hci_conn *conn;
1453
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001454 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001455
1456 if (!status)
1457 return;
1458
1459 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1460 if (!cp)
1461 return;
1462
1463 hci_dev_lock(hdev);
1464
1465 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1466 if (conn) {
1467 if (conn->state == BT_CONFIG) {
1468 hci_proto_connect_cfm(conn, status);
1469 hci_conn_put(conn);
1470 }
1471 }
1472
1473 hci_dev_unlock(hdev);
1474}
1475
Johan Hedberg127178d2010-11-18 22:22:29 +02001476static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001477 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001478{
Johan Hedberg392599b2010-11-18 22:22:28 +02001479 if (conn->state != BT_CONFIG || !conn->out)
1480 return 0;
1481
Johan Hedberg765c2a92011-01-19 12:06:52 +05301482 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001483 return 0;
1484
1485 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001486 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001487 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1488 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001489 return 0;
1490
Johan Hedberg392599b2010-11-18 22:22:28 +02001491 return 1;
1492}
1493
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001494static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001495 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001496{
1497 struct hci_cp_remote_name_req cp;
1498
1499 memset(&cp, 0, sizeof(cp));
1500
1501 bacpy(&cp.bdaddr, &e->data.bdaddr);
1502 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1503 cp.pscan_mode = e->data.pscan_mode;
1504 cp.clock_offset = e->data.clock_offset;
1505
1506 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1507}
1508
Johan Hedbergb644ba32012-01-17 21:48:47 +02001509static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001510{
1511 struct discovery_state *discov = &hdev->discovery;
1512 struct inquiry_entry *e;
1513
Johan Hedbergb644ba32012-01-17 21:48:47 +02001514 if (list_empty(&discov->resolve))
1515 return false;
1516
1517 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001518 if (!e)
1519 return false;
1520
Johan Hedbergb644ba32012-01-17 21:48:47 +02001521 if (hci_resolve_name(hdev, e) == 0) {
1522 e->name_state = NAME_PENDING;
1523 return true;
1524 }
1525
1526 return false;
1527}
1528
1529static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001530 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001531{
1532 struct discovery_state *discov = &hdev->discovery;
1533 struct inquiry_entry *e;
1534
1535 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001536 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1537 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001538
1539 if (discov->state == DISCOVERY_STOPPED)
1540 return;
1541
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001542 if (discov->state == DISCOVERY_STOPPING)
1543 goto discov_complete;
1544
1545 if (discov->state != DISCOVERY_RESOLVING)
1546 return;
1547
1548 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001549 /* If the device was not found in a list of found devices names of which
1550 * are pending. there is no need to continue resolving a next name as it
1551 * will be done upon receiving another Remote Name Request Complete
1552 * Event */
1553 if (!e)
1554 return;
1555
1556 list_del(&e->list);
1557 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001558 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001559 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1560 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001561 } else {
1562 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001563 }
1564
Johan Hedbergb644ba32012-01-17 21:48:47 +02001565 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001566 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001567
1568discov_complete:
1569 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1570}
1571
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001572static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1573{
Johan Hedberg127178d2010-11-18 22:22:29 +02001574 struct hci_cp_remote_name_req *cp;
1575 struct hci_conn *conn;
1576
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001577 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001578
1579 /* If successful wait for the name req complete event before
1580 * checking for the need to do authentication */
1581 if (!status)
1582 return;
1583
1584 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1585 if (!cp)
1586 return;
1587
1588 hci_dev_lock(hdev);
1589
1590 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001591
1592 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1593 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1594
Johan Hedberg79c6c702011-04-28 11:28:55 -07001595 if (!conn)
1596 goto unlock;
1597
1598 if (!hci_outgoing_auth_needed(hdev, conn))
1599 goto unlock;
1600
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001601 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001602 struct hci_cp_auth_requested cp;
1603 cp.handle = __cpu_to_le16(conn->handle);
1604 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1605 }
1606
Johan Hedberg79c6c702011-04-28 11:28:55 -07001607unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001608 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001609}
1610
Marcel Holtmann769be972008-07-14 20:13:49 +02001611static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1612{
1613 struct hci_cp_read_remote_features *cp;
1614 struct hci_conn *conn;
1615
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001616 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001617
1618 if (!status)
1619 return;
1620
1621 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1622 if (!cp)
1623 return;
1624
1625 hci_dev_lock(hdev);
1626
1627 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1628 if (conn) {
1629 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001630 hci_proto_connect_cfm(conn, status);
1631 hci_conn_put(conn);
1632 }
1633 }
1634
1635 hci_dev_unlock(hdev);
1636}
1637
1638static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1639{
1640 struct hci_cp_read_remote_ext_features *cp;
1641 struct hci_conn *conn;
1642
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001643 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001644
1645 if (!status)
1646 return;
1647
1648 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1649 if (!cp)
1650 return;
1651
1652 hci_dev_lock(hdev);
1653
1654 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1655 if (conn) {
1656 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001657 hci_proto_connect_cfm(conn, status);
1658 hci_conn_put(conn);
1659 }
1660 }
1661
1662 hci_dev_unlock(hdev);
1663}
1664
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001665static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1666{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001667 struct hci_cp_setup_sync_conn *cp;
1668 struct hci_conn *acl, *sco;
1669 __u16 handle;
1670
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001671 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001672
1673 if (!status)
1674 return;
1675
1676 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1677 if (!cp)
1678 return;
1679
1680 handle = __le16_to_cpu(cp->handle);
1681
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001682 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001683
1684 hci_dev_lock(hdev);
1685
1686 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001687 if (acl) {
1688 sco = acl->link;
1689 if (sco) {
1690 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001691
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001692 hci_proto_connect_cfm(sco, status);
1693 hci_conn_del(sco);
1694 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001695 }
1696
1697 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001698}
1699
1700static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1701{
1702 struct hci_cp_sniff_mode *cp;
1703 struct hci_conn *conn;
1704
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001705 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001706
1707 if (!status)
1708 return;
1709
1710 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1711 if (!cp)
1712 return;
1713
1714 hci_dev_lock(hdev);
1715
1716 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001717 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001718 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001719
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001720 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001721 hci_sco_setup(conn, status);
1722 }
1723
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001724 hci_dev_unlock(hdev);
1725}
1726
1727static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1728{
1729 struct hci_cp_exit_sniff_mode *cp;
1730 struct hci_conn *conn;
1731
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001732 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001733
1734 if (!status)
1735 return;
1736
1737 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1738 if (!cp)
1739 return;
1740
1741 hci_dev_lock(hdev);
1742
1743 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001744 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001745 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001746
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001747 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001748 hci_sco_setup(conn, status);
1749 }
1750
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001751 hci_dev_unlock(hdev);
1752}
1753
Johan Hedberg88c3df12012-02-09 14:27:38 +02001754static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1755{
1756 struct hci_cp_disconnect *cp;
1757 struct hci_conn *conn;
1758
1759 if (!status)
1760 return;
1761
1762 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1763 if (!cp)
1764 return;
1765
1766 hci_dev_lock(hdev);
1767
1768 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1769 if (conn)
1770 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001771 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001772
1773 hci_dev_unlock(hdev);
1774}
1775
Ville Tervofcd89c02011-02-10 22:38:47 -03001776static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1777{
Ville Tervofcd89c02011-02-10 22:38:47 -03001778 struct hci_conn *conn;
1779
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001780 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Ville Tervofcd89c02011-02-10 22:38:47 -03001781
Ville Tervofcd89c02011-02-10 22:38:47 -03001782 if (status) {
Andre Guedesf00a06a2012-07-27 15:10:13 -03001783 hci_dev_lock(hdev);
Ville Tervofcd89c02011-02-10 22:38:47 -03001784
Andre Guedes0c95ab72012-07-27 15:10:14 -03001785 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001786 if (!conn) {
1787 hci_dev_unlock(hdev);
1788 return;
1789 }
1790
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001791 BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001792
1793 conn->state = BT_CLOSED;
Andre Guedes0c95ab72012-07-27 15:10:14 -03001794 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Andre Guedesf00a06a2012-07-27 15:10:13 -03001795 conn->dst_type, status);
1796 hci_proto_connect_cfm(conn, status);
1797 hci_conn_del(conn);
1798
1799 hci_dev_unlock(hdev);
1800 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001801}
1802
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001803static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1804{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001805 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001806}
1807
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001808static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1809{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001810 struct hci_cp_create_phy_link *cp;
1811
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001812 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001813
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001814 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1815 if (!cp)
1816 return;
1817
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001818 hci_dev_lock(hdev);
1819
1820 if (status) {
1821 struct hci_conn *hcon;
1822
1823 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1824 if (hcon)
1825 hci_conn_del(hcon);
1826 } else {
1827 amp_write_remote_assoc(hdev, cp->phy_handle);
1828 }
1829
1830 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001831}
1832
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001833static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1834{
1835 struct hci_cp_accept_phy_link *cp;
1836
1837 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1838
1839 if (status)
1840 return;
1841
1842 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1843 if (!cp)
1844 return;
1845
1846 amp_write_remote_assoc(hdev, cp->phy_handle);
1847}
1848
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001849static void hci_cs_create_logical_link(struct hci_dev *hdev, u8 status)
1850{
1851 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1852}
1853
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001854static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001855{
1856 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001857 struct discovery_state *discov = &hdev->discovery;
1858 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001859
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001860 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001861
Johan Hedberg23bb5762010-12-21 23:01:27 +02001862 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001863
1864 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001865
1866 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1867 return;
1868
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001869 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001870 return;
1871
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001872 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001873
Andre Guedes343f9352012-02-17 20:39:37 -03001874 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001875 goto unlock;
1876
1877 if (list_empty(&discov->resolve)) {
1878 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1879 goto unlock;
1880 }
1881
1882 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1883 if (e && hci_resolve_name(hdev, e) == 0) {
1884 e->name_state = NAME_PENDING;
1885 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1886 } else {
1887 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1888 }
1889
1890unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001891 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001892}
1893
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001894static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001896 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001897 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898 int num_rsp = *((__u8 *) skb->data);
1899
1900 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1901
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001902 if (!num_rsp)
1903 return;
1904
Andre Guedes1519cc12012-03-21 00:03:38 -03001905 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1906 return;
1907
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001909
Johan Hedberge17acd42011-03-30 23:57:16 +03001910 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001911 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001912
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 bacpy(&data.bdaddr, &info->bdaddr);
1914 data.pscan_rep_mode = info->pscan_rep_mode;
1915 data.pscan_period_mode = info->pscan_period_mode;
1916 data.pscan_mode = info->pscan_mode;
1917 memcpy(data.dev_class, info->dev_class, 3);
1918 data.clock_offset = info->clock_offset;
1919 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001920 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001921
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001922 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001923 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001924 info->dev_class, 0, !name_known, ssp, NULL,
1925 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001927
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 hci_dev_unlock(hdev);
1929}
1930
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001931static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001933 struct hci_ev_conn_complete *ev = (void *) skb->data;
1934 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001936 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001937
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001939
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001940 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001941 if (!conn) {
1942 if (ev->link_type != SCO_LINK)
1943 goto unlock;
1944
1945 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1946 if (!conn)
1947 goto unlock;
1948
1949 conn->type = SCO_LINK;
1950 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001951
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001952 if (!ev->status) {
1953 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001954
1955 if (conn->type == ACL_LINK) {
1956 conn->state = BT_CONFIG;
1957 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001958
1959 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1960 !hci_find_link_key(hdev, &ev->bdaddr))
1961 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1962 else
1963 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001964 } else
1965 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001966
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001967 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001968 hci_conn_add_sysfs(conn);
1969
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001970 if (test_bit(HCI_AUTH, &hdev->flags))
1971 conn->link_mode |= HCI_LM_AUTH;
1972
1973 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1974 conn->link_mode |= HCI_LM_ENCRYPT;
1975
1976 /* Get remote features */
1977 if (conn->type == ACL_LINK) {
1978 struct hci_cp_read_remote_features cp;
1979 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001980 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001981 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001982 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001983
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001984 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001985 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001986 struct hci_cp_change_conn_ptype cp;
1987 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001988 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001989 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1990 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001991 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001992 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001993 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001994 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001995 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001996 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001997 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001998
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001999 if (conn->type == ACL_LINK)
2000 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07002001
Marcel Holtmann769be972008-07-14 20:13:49 +02002002 if (ev->status) {
2003 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002004 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01002005 } else if (ev->link_type != ACL_LINK)
2006 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002007
2008unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002010
2011 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012}
2013
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002014static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002016 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017 int mask = hdev->link_mode;
2018
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002019 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002020 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002021
2022 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
2023
Szymon Janc138d22e2011-02-17 16:44:23 +01002024 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002025 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02002027 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002029
2030 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002031
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002032 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2033 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02002034 memcpy(ie->data.dev_class, ev->dev_class, 3);
2035
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002036 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
2037 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002039 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
2040 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03002041 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002042 hci_dev_unlock(hdev);
2043 return;
2044 }
2045 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002046
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 memcpy(conn->dev_class, ev->dev_class, 3);
2048 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002049
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050 hci_dev_unlock(hdev);
2051
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002052 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
2053 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002055 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002057 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
2058 cp.role = 0x00; /* Become master */
2059 else
2060 cp.role = 0x01; /* Remain slave */
2061
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002062 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
2063 &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002064 } else {
2065 struct hci_cp_accept_sync_conn_req cp;
2066
2067 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002068 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002069
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03002070 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
2071 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
2072 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002073 cp.content_format = cpu_to_le16(hdev->voice_setting);
2074 cp.retrans_effort = 0xff;
2075
2076 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002077 sizeof(cp), &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002078 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079 } else {
2080 /* Connection rejected */
2081 struct hci_cp_reject_conn_req cp;
2082
2083 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002084 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002085 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 }
2087}
2088
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02002089static u8 hci_to_mgmt_reason(u8 err)
2090{
2091 switch (err) {
2092 case HCI_ERROR_CONNECTION_TIMEOUT:
2093 return MGMT_DEV_DISCONN_TIMEOUT;
2094 case HCI_ERROR_REMOTE_USER_TERM:
2095 case HCI_ERROR_REMOTE_LOW_RESOURCES:
2096 case HCI_ERROR_REMOTE_POWER_OFF:
2097 return MGMT_DEV_DISCONN_REMOTE;
2098 case HCI_ERROR_LOCAL_HOST_TERM:
2099 return MGMT_DEV_DISCONN_LOCAL_HOST;
2100 default:
2101 return MGMT_DEV_DISCONN_UNKNOWN;
2102 }
2103}
2104
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002105static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002106{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002107 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002108 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002110 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112 hci_dev_lock(hdev);
2113
Marcel Holtmann04837f62006-07-03 10:02:33 +02002114 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02002115 if (!conn)
2116 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002117
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002118 if (ev->status == 0)
2119 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120
Johan Hedbergb644ba32012-01-17 21:48:47 +02002121 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002122 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02002123 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02002124 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002125 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02002126 } else {
2127 u8 reason = hci_to_mgmt_reason(ev->reason);
2128
Johan Hedbergafc747a2012-01-15 18:11:07 +02002129 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02002130 conn->dst_type, reason);
2131 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002132 }
Johan Hedbergf7520542011-01-20 12:34:39 +02002133
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002134 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05302135 if (conn->type == ACL_LINK && conn->flush_key)
2136 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002137 hci_proto_disconn_cfm(conn, ev->reason);
2138 hci_conn_del(conn);
2139 }
Johan Hedbergf7520542011-01-20 12:34:39 +02002140
2141unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142 hci_dev_unlock(hdev);
2143}
2144
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002145static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002146{
2147 struct hci_ev_auth_complete *ev = (void *) skb->data;
2148 struct hci_conn *conn;
2149
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002150 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002151
2152 hci_dev_lock(hdev);
2153
2154 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002155 if (!conn)
2156 goto unlock;
2157
2158 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002159 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002160 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002161 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03002162 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002163 conn->link_mode |= HCI_LM_AUTH;
2164 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03002165 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002166 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02002167 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002168 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002169 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002170
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002171 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
2172 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002173
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002174 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002175 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002176 struct hci_cp_set_conn_encrypt cp;
2177 cp.handle = ev->handle;
2178 cp.encrypt = 0x01;
2179 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002180 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002181 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002182 conn->state = BT_CONNECTED;
2183 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002184 hci_conn_put(conn);
2185 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002186 } else {
2187 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002188
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002189 hci_conn_hold(conn);
2190 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
2191 hci_conn_put(conn);
2192 }
2193
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002194 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002195 if (!ev->status) {
2196 struct hci_cp_set_conn_encrypt cp;
2197 cp.handle = ev->handle;
2198 cp.encrypt = 0x01;
2199 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002200 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002201 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002202 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002203 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002204 }
2205 }
2206
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002207unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002208 hci_dev_unlock(hdev);
2209}
2210
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002211static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002212{
Johan Hedberg127178d2010-11-18 22:22:29 +02002213 struct hci_ev_remote_name *ev = (void *) skb->data;
2214 struct hci_conn *conn;
2215
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002216 BT_DBG("%s", hdev->name);
2217
2218 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002219
2220 hci_dev_lock(hdev);
2221
2222 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002223
2224 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2225 goto check_auth;
2226
2227 if (ev->status == 0)
2228 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002229 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002230 else
2231 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2232
2233check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002234 if (!conn)
2235 goto unlock;
2236
2237 if (!hci_outgoing_auth_needed(hdev, conn))
2238 goto unlock;
2239
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002240 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002241 struct hci_cp_auth_requested cp;
2242 cp.handle = __cpu_to_le16(conn->handle);
2243 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2244 }
2245
Johan Hedberg79c6c702011-04-28 11:28:55 -07002246unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002247 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002248}
2249
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002250static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002251{
2252 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2253 struct hci_conn *conn;
2254
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002255 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002256
2257 hci_dev_lock(hdev);
2258
2259 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2260 if (conn) {
2261 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002262 if (ev->encrypt) {
2263 /* Encryption implies authentication */
2264 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002265 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002266 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002267 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002268 conn->link_mode &= ~HCI_LM_ENCRYPT;
2269 }
2270
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002271 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002272
Gustavo Padovana7d77232012-05-13 03:20:07 -03002273 if (ev->status && conn->state == BT_CONNECTED) {
Gustavo Padovand839c812012-05-16 12:17:12 -03002274 hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE);
Gustavo Padovana7d77232012-05-13 03:20:07 -03002275 hci_conn_put(conn);
2276 goto unlock;
2277 }
2278
Marcel Holtmannf8558552008-07-14 20:13:49 +02002279 if (conn->state == BT_CONFIG) {
2280 if (!ev->status)
2281 conn->state = BT_CONNECTED;
2282
2283 hci_proto_connect_cfm(conn, ev->status);
2284 hci_conn_put(conn);
2285 } else
2286 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002287 }
2288
Gustavo Padovana7d77232012-05-13 03:20:07 -03002289unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002290 hci_dev_unlock(hdev);
2291}
2292
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002293static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2294 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002295{
2296 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2297 struct hci_conn *conn;
2298
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002299 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002300
2301 hci_dev_lock(hdev);
2302
2303 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2304 if (conn) {
2305 if (!ev->status)
2306 conn->link_mode |= HCI_LM_SECURE;
2307
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002308 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002309
2310 hci_key_change_cfm(conn, ev->status);
2311 }
2312
2313 hci_dev_unlock(hdev);
2314}
2315
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002316static void hci_remote_features_evt(struct hci_dev *hdev,
2317 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002318{
2319 struct hci_ev_remote_features *ev = (void *) skb->data;
2320 struct hci_conn *conn;
2321
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002322 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002323
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002324 hci_dev_lock(hdev);
2325
2326 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002327 if (!conn)
2328 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002329
Johan Hedbergccd556f2010-11-10 17:11:51 +02002330 if (!ev->status)
2331 memcpy(conn->features, ev->features, 8);
2332
2333 if (conn->state != BT_CONFIG)
2334 goto unlock;
2335
2336 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2337 struct hci_cp_read_remote_ext_features cp;
2338 cp.handle = ev->handle;
2339 cp.page = 0x01;
2340 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002341 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002342 goto unlock;
2343 }
2344
Johan Hedberg671267b2012-05-12 16:11:50 -03002345 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002346 struct hci_cp_remote_name_req cp;
2347 memset(&cp, 0, sizeof(cp));
2348 bacpy(&cp.bdaddr, &conn->dst);
2349 cp.pscan_rep_mode = 0x02;
2350 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002351 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2352 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002353 conn->dst_type, 0, NULL, 0,
2354 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002355
Johan Hedberg127178d2010-11-18 22:22:29 +02002356 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002357 conn->state = BT_CONNECTED;
2358 hci_proto_connect_cfm(conn, ev->status);
2359 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002360 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002361
Johan Hedbergccd556f2010-11-10 17:11:51 +02002362unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002363 hci_dev_unlock(hdev);
2364}
2365
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002366static void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002367{
2368 BT_DBG("%s", hdev->name);
2369}
2370
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002371static void hci_qos_setup_complete_evt(struct hci_dev *hdev,
2372 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002373{
2374 BT_DBG("%s", hdev->name);
2375}
2376
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002377static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002378{
2379 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2380 __u16 opcode;
2381
2382 skb_pull(skb, sizeof(*ev));
2383
2384 opcode = __le16_to_cpu(ev->opcode);
2385
2386 switch (opcode) {
2387 case HCI_OP_INQUIRY_CANCEL:
2388 hci_cc_inquiry_cancel(hdev, skb);
2389 break;
2390
Andre Guedes4d934832012-03-21 00:03:35 -03002391 case HCI_OP_PERIODIC_INQ:
2392 hci_cc_periodic_inq(hdev, skb);
2393 break;
2394
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002395 case HCI_OP_EXIT_PERIODIC_INQ:
2396 hci_cc_exit_periodic_inq(hdev, skb);
2397 break;
2398
2399 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2400 hci_cc_remote_name_req_cancel(hdev, skb);
2401 break;
2402
2403 case HCI_OP_ROLE_DISCOVERY:
2404 hci_cc_role_discovery(hdev, skb);
2405 break;
2406
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002407 case HCI_OP_READ_LINK_POLICY:
2408 hci_cc_read_link_policy(hdev, skb);
2409 break;
2410
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002411 case HCI_OP_WRITE_LINK_POLICY:
2412 hci_cc_write_link_policy(hdev, skb);
2413 break;
2414
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002415 case HCI_OP_READ_DEF_LINK_POLICY:
2416 hci_cc_read_def_link_policy(hdev, skb);
2417 break;
2418
2419 case HCI_OP_WRITE_DEF_LINK_POLICY:
2420 hci_cc_write_def_link_policy(hdev, skb);
2421 break;
2422
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002423 case HCI_OP_RESET:
2424 hci_cc_reset(hdev, skb);
2425 break;
2426
2427 case HCI_OP_WRITE_LOCAL_NAME:
2428 hci_cc_write_local_name(hdev, skb);
2429 break;
2430
2431 case HCI_OP_READ_LOCAL_NAME:
2432 hci_cc_read_local_name(hdev, skb);
2433 break;
2434
2435 case HCI_OP_WRITE_AUTH_ENABLE:
2436 hci_cc_write_auth_enable(hdev, skb);
2437 break;
2438
2439 case HCI_OP_WRITE_ENCRYPT_MODE:
2440 hci_cc_write_encrypt_mode(hdev, skb);
2441 break;
2442
2443 case HCI_OP_WRITE_SCAN_ENABLE:
2444 hci_cc_write_scan_enable(hdev, skb);
2445 break;
2446
2447 case HCI_OP_READ_CLASS_OF_DEV:
2448 hci_cc_read_class_of_dev(hdev, skb);
2449 break;
2450
2451 case HCI_OP_WRITE_CLASS_OF_DEV:
2452 hci_cc_write_class_of_dev(hdev, skb);
2453 break;
2454
2455 case HCI_OP_READ_VOICE_SETTING:
2456 hci_cc_read_voice_setting(hdev, skb);
2457 break;
2458
2459 case HCI_OP_WRITE_VOICE_SETTING:
2460 hci_cc_write_voice_setting(hdev, skb);
2461 break;
2462
2463 case HCI_OP_HOST_BUFFER_SIZE:
2464 hci_cc_host_buffer_size(hdev, skb);
2465 break;
2466
Marcel Holtmann333140b2008-07-14 20:13:48 +02002467 case HCI_OP_WRITE_SSP_MODE:
2468 hci_cc_write_ssp_mode(hdev, skb);
2469 break;
2470
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002471 case HCI_OP_READ_LOCAL_VERSION:
2472 hci_cc_read_local_version(hdev, skb);
2473 break;
2474
2475 case HCI_OP_READ_LOCAL_COMMANDS:
2476 hci_cc_read_local_commands(hdev, skb);
2477 break;
2478
2479 case HCI_OP_READ_LOCAL_FEATURES:
2480 hci_cc_read_local_features(hdev, skb);
2481 break;
2482
Andre Guedes971e3a42011-06-30 19:20:52 -03002483 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2484 hci_cc_read_local_ext_features(hdev, skb);
2485 break;
2486
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002487 case HCI_OP_READ_BUFFER_SIZE:
2488 hci_cc_read_buffer_size(hdev, skb);
2489 break;
2490
2491 case HCI_OP_READ_BD_ADDR:
2492 hci_cc_read_bd_addr(hdev, skb);
2493 break;
2494
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002495 case HCI_OP_READ_DATA_BLOCK_SIZE:
2496 hci_cc_read_data_block_size(hdev, skb);
2497 break;
2498
Johan Hedberg23bb5762010-12-21 23:01:27 +02002499 case HCI_OP_WRITE_CA_TIMEOUT:
2500 hci_cc_write_ca_timeout(hdev, skb);
2501 break;
2502
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002503 case HCI_OP_READ_FLOW_CONTROL_MODE:
2504 hci_cc_read_flow_control_mode(hdev, skb);
2505 break;
2506
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002507 case HCI_OP_READ_LOCAL_AMP_INFO:
2508 hci_cc_read_local_amp_info(hdev, skb);
2509 break;
2510
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002511 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2512 hci_cc_read_local_amp_assoc(hdev, skb);
2513 break;
2514
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002515 case HCI_OP_DELETE_STORED_LINK_KEY:
2516 hci_cc_delete_stored_link_key(hdev, skb);
2517 break;
2518
Johan Hedbergd5859e22011-01-25 01:19:58 +02002519 case HCI_OP_SET_EVENT_MASK:
2520 hci_cc_set_event_mask(hdev, skb);
2521 break;
2522
2523 case HCI_OP_WRITE_INQUIRY_MODE:
2524 hci_cc_write_inquiry_mode(hdev, skb);
2525 break;
2526
2527 case HCI_OP_READ_INQ_RSP_TX_POWER:
2528 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2529 break;
2530
2531 case HCI_OP_SET_EVENT_FLT:
2532 hci_cc_set_event_flt(hdev, skb);
2533 break;
2534
Johan Hedberg980e1a52011-01-22 06:10:07 +02002535 case HCI_OP_PIN_CODE_REPLY:
2536 hci_cc_pin_code_reply(hdev, skb);
2537 break;
2538
2539 case HCI_OP_PIN_CODE_NEG_REPLY:
2540 hci_cc_pin_code_neg_reply(hdev, skb);
2541 break;
2542
Szymon Jancc35938b2011-03-22 13:12:21 +01002543 case HCI_OP_READ_LOCAL_OOB_DATA:
2544 hci_cc_read_local_oob_data_reply(hdev, skb);
2545 break;
2546
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002547 case HCI_OP_LE_READ_BUFFER_SIZE:
2548 hci_cc_le_read_buffer_size(hdev, skb);
2549 break;
2550
Johan Hedberg8fa19092012-10-19 20:57:49 +03002551 case HCI_OP_LE_READ_ADV_TX_POWER:
2552 hci_cc_le_read_adv_tx_power(hdev, skb);
2553 break;
2554
Johan Hedberge36b04c2012-10-19 20:57:47 +03002555 case HCI_OP_LE_SET_EVENT_MASK:
2556 hci_cc_le_set_event_mask(hdev, skb);
2557 break;
2558
Johan Hedberga5c29682011-02-19 12:05:57 -03002559 case HCI_OP_USER_CONFIRM_REPLY:
2560 hci_cc_user_confirm_reply(hdev, skb);
2561 break;
2562
2563 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2564 hci_cc_user_confirm_neg_reply(hdev, skb);
2565 break;
2566
Brian Gix1143d452011-11-23 08:28:34 -08002567 case HCI_OP_USER_PASSKEY_REPLY:
2568 hci_cc_user_passkey_reply(hdev, skb);
2569 break;
2570
2571 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2572 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002573 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002574
2575 case HCI_OP_LE_SET_SCAN_PARAM:
2576 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002577 break;
2578
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002579 case HCI_OP_LE_SET_SCAN_ENABLE:
2580 hci_cc_le_set_scan_enable(hdev, skb);
2581 break;
2582
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002583 case HCI_OP_LE_LTK_REPLY:
2584 hci_cc_le_ltk_reply(hdev, skb);
2585 break;
2586
2587 case HCI_OP_LE_LTK_NEG_REPLY:
2588 hci_cc_le_ltk_neg_reply(hdev, skb);
2589 break;
2590
Andre Guedesf9b49302011-06-30 19:20:53 -03002591 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2592 hci_cc_write_le_host_supported(hdev, skb);
2593 break;
2594
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002595 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2596 hci_cc_write_remote_amp_assoc(hdev, skb);
2597 break;
2598
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002599 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002600 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002601 break;
2602 }
2603
Ville Tervo6bd32322011-02-16 16:32:41 +02002604 if (ev->opcode != HCI_OP_NOP)
2605 del_timer(&hdev->cmd_timer);
2606
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002607 if (ev->ncmd) {
2608 atomic_set(&hdev->cmd_cnt, 1);
2609 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002610 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002611 }
2612}
2613
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002614static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002615{
2616 struct hci_ev_cmd_status *ev = (void *) skb->data;
2617 __u16 opcode;
2618
2619 skb_pull(skb, sizeof(*ev));
2620
2621 opcode = __le16_to_cpu(ev->opcode);
2622
2623 switch (opcode) {
2624 case HCI_OP_INQUIRY:
2625 hci_cs_inquiry(hdev, ev->status);
2626 break;
2627
2628 case HCI_OP_CREATE_CONN:
2629 hci_cs_create_conn(hdev, ev->status);
2630 break;
2631
2632 case HCI_OP_ADD_SCO:
2633 hci_cs_add_sco(hdev, ev->status);
2634 break;
2635
Marcel Holtmannf8558552008-07-14 20:13:49 +02002636 case HCI_OP_AUTH_REQUESTED:
2637 hci_cs_auth_requested(hdev, ev->status);
2638 break;
2639
2640 case HCI_OP_SET_CONN_ENCRYPT:
2641 hci_cs_set_conn_encrypt(hdev, ev->status);
2642 break;
2643
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002644 case HCI_OP_REMOTE_NAME_REQ:
2645 hci_cs_remote_name_req(hdev, ev->status);
2646 break;
2647
Marcel Holtmann769be972008-07-14 20:13:49 +02002648 case HCI_OP_READ_REMOTE_FEATURES:
2649 hci_cs_read_remote_features(hdev, ev->status);
2650 break;
2651
2652 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2653 hci_cs_read_remote_ext_features(hdev, ev->status);
2654 break;
2655
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002656 case HCI_OP_SETUP_SYNC_CONN:
2657 hci_cs_setup_sync_conn(hdev, ev->status);
2658 break;
2659
2660 case HCI_OP_SNIFF_MODE:
2661 hci_cs_sniff_mode(hdev, ev->status);
2662 break;
2663
2664 case HCI_OP_EXIT_SNIFF_MODE:
2665 hci_cs_exit_sniff_mode(hdev, ev->status);
2666 break;
2667
Johan Hedberg8962ee72011-01-20 12:40:27 +02002668 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002669 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002670 break;
2671
Ville Tervofcd89c02011-02-10 22:38:47 -03002672 case HCI_OP_LE_CREATE_CONN:
2673 hci_cs_le_create_conn(hdev, ev->status);
2674 break;
2675
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002676 case HCI_OP_LE_START_ENC:
2677 hci_cs_le_start_enc(hdev, ev->status);
2678 break;
2679
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002680 case HCI_OP_CREATE_PHY_LINK:
2681 hci_cs_create_phylink(hdev, ev->status);
2682 break;
2683
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002684 case HCI_OP_ACCEPT_PHY_LINK:
2685 hci_cs_accept_phylink(hdev, ev->status);
2686 break;
2687
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02002688 case HCI_OP_CREATE_LOGICAL_LINK:
2689 hci_cs_create_logical_link(hdev, ev->status);
2690 break;
2691
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002692 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002693 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002694 break;
2695 }
2696
Ville Tervo6bd32322011-02-16 16:32:41 +02002697 if (ev->opcode != HCI_OP_NOP)
2698 del_timer(&hdev->cmd_timer);
2699
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002700 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002701 atomic_set(&hdev->cmd_cnt, 1);
2702 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002703 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002704 }
2705}
2706
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002707static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002708{
2709 struct hci_ev_role_change *ev = (void *) skb->data;
2710 struct hci_conn *conn;
2711
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002712 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002713
2714 hci_dev_lock(hdev);
2715
2716 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2717 if (conn) {
2718 if (!ev->status) {
2719 if (ev->role)
2720 conn->link_mode &= ~HCI_LM_MASTER;
2721 else
2722 conn->link_mode |= HCI_LM_MASTER;
2723 }
2724
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002725 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002726
2727 hci_role_switch_cfm(conn, ev->status, ev->role);
2728 }
2729
2730 hci_dev_unlock(hdev);
2731}
2732
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002733static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002734{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002735 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002736 int i;
2737
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002738 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2739 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2740 return;
2741 }
2742
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002743 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002744 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745 BT_DBG("%s bad parameters", hdev->name);
2746 return;
2747 }
2748
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002749 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2750
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002751 for (i = 0; i < ev->num_hndl; i++) {
2752 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002753 struct hci_conn *conn;
2754 __u16 handle, count;
2755
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002756 handle = __le16_to_cpu(info->handle);
2757 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002758
2759 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002760 if (!conn)
2761 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002762
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002763 conn->sent -= count;
2764
2765 switch (conn->type) {
2766 case ACL_LINK:
2767 hdev->acl_cnt += count;
2768 if (hdev->acl_cnt > hdev->acl_pkts)
2769 hdev->acl_cnt = hdev->acl_pkts;
2770 break;
2771
2772 case LE_LINK:
2773 if (hdev->le_pkts) {
2774 hdev->le_cnt += count;
2775 if (hdev->le_cnt > hdev->le_pkts)
2776 hdev->le_cnt = hdev->le_pkts;
2777 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002778 hdev->acl_cnt += count;
2779 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002780 hdev->acl_cnt = hdev->acl_pkts;
2781 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002782 break;
2783
2784 case SCO_LINK:
2785 hdev->sco_cnt += count;
2786 if (hdev->sco_cnt > hdev->sco_pkts)
2787 hdev->sco_cnt = hdev->sco_pkts;
2788 break;
2789
2790 default:
2791 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2792 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002793 }
2794 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002795
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002796 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797}
2798
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002799static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2800 __u16 handle)
2801{
2802 struct hci_chan *chan;
2803
2804 switch (hdev->dev_type) {
2805 case HCI_BREDR:
2806 return hci_conn_hash_lookup_handle(hdev, handle);
2807 case HCI_AMP:
2808 chan = hci_chan_lookup_handle(hdev, handle);
2809 if (chan)
2810 return chan->conn;
2811 break;
2812 default:
2813 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2814 break;
2815 }
2816
2817 return NULL;
2818}
2819
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002820static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002821{
2822 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2823 int i;
2824
2825 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2826 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2827 return;
2828 }
2829
2830 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002831 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002832 BT_DBG("%s bad parameters", hdev->name);
2833 return;
2834 }
2835
2836 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002837 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002838
2839 for (i = 0; i < ev->num_hndl; i++) {
2840 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002841 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002842 __u16 handle, block_count;
2843
2844 handle = __le16_to_cpu(info->handle);
2845 block_count = __le16_to_cpu(info->blocks);
2846
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002847 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002848 if (!conn)
2849 continue;
2850
2851 conn->sent -= block_count;
2852
2853 switch (conn->type) {
2854 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002855 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002856 hdev->block_cnt += block_count;
2857 if (hdev->block_cnt > hdev->num_blocks)
2858 hdev->block_cnt = hdev->num_blocks;
2859 break;
2860
2861 default:
2862 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2863 break;
2864 }
2865 }
2866
2867 queue_work(hdev->workqueue, &hdev->tx_work);
2868}
2869
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002870static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002872 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002873 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002875 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876
2877 hci_dev_lock(hdev);
2878
Marcel Holtmann04837f62006-07-03 10:02:33 +02002879 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2880 if (conn) {
2881 conn->mode = ev->mode;
2882 conn->interval = __le16_to_cpu(ev->interval);
2883
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002884 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2885 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002886 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002887 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002888 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002889 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002890 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002891
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002892 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002893 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002894 }
2895
2896 hci_dev_unlock(hdev);
2897}
2898
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002899static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002900{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002901 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2902 struct hci_conn *conn;
2903
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002904 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002905
2906 hci_dev_lock(hdev);
2907
2908 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002909 if (!conn)
2910 goto unlock;
2911
2912 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002913 hci_conn_hold(conn);
2914 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2915 hci_conn_put(conn);
2916 }
2917
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002918 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002919 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002920 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002921 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002922 u8 secure;
2923
2924 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2925 secure = 1;
2926 else
2927 secure = 0;
2928
Johan Hedberg744cf192011-11-08 20:40:14 +02002929 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002930 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002931
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002932unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002933 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002934}
2935
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002936static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002937{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002938 struct hci_ev_link_key_req *ev = (void *) skb->data;
2939 struct hci_cp_link_key_reply cp;
2940 struct hci_conn *conn;
2941 struct link_key *key;
2942
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002943 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002944
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002945 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002946 return;
2947
2948 hci_dev_lock(hdev);
2949
2950 key = hci_find_link_key(hdev, &ev->bdaddr);
2951 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002952 BT_DBG("%s link key not found for %pMR", hdev->name,
2953 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002954 goto not_found;
2955 }
2956
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002957 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2958 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002959
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002960 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002961 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002962 BT_DBG("%s ignoring debug key", hdev->name);
2963 goto not_found;
2964 }
2965
2966 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002967 if (conn) {
2968 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002969 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002970 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2971 goto not_found;
2972 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002973
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002974 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002975 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002976 BT_DBG("%s ignoring key unauthenticated for high security",
2977 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002978 goto not_found;
2979 }
2980
2981 conn->key_type = key->type;
2982 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002983 }
2984
2985 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002986 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002987
2988 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2989
2990 hci_dev_unlock(hdev);
2991
2992 return;
2993
2994not_found:
2995 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2996 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997}
2998
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002999static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003001 struct hci_ev_link_key_notify *ev = (void *) skb->data;
3002 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003003 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003004
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003005 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003006
3007 hci_dev_lock(hdev);
3008
3009 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3010 if (conn) {
3011 hci_conn_hold(conn);
3012 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02003013 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02003014
3015 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
3016 conn->key_type = ev->key_type;
3017
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003018 hci_conn_put(conn);
3019 }
3020
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003021 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07003022 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003023 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003024
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003025 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003026}
3027
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003028static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02003029{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003030 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02003031 struct hci_conn *conn;
3032
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003033 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02003034
3035 hci_dev_lock(hdev);
3036
3037 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003038 if (conn && !ev->status) {
3039 struct inquiry_entry *ie;
3040
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003041 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3042 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003043 ie->data.clock_offset = ev->clock_offset;
3044 ie->timestamp = jiffies;
3045 }
3046 }
3047
3048 hci_dev_unlock(hdev);
3049}
3050
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003051static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02003052{
3053 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
3054 struct hci_conn *conn;
3055
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003056 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02003057
3058 hci_dev_lock(hdev);
3059
3060 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3061 if (conn && !ev->status)
3062 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
3063
3064 hci_dev_unlock(hdev);
3065}
3066
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003067static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003068{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003069 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003070 struct inquiry_entry *ie;
3071
3072 BT_DBG("%s", hdev->name);
3073
3074 hci_dev_lock(hdev);
3075
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003076 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3077 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003078 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
3079 ie->timestamp = jiffies;
3080 }
3081
3082 hci_dev_unlock(hdev);
3083}
3084
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003085static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
3086 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003087{
3088 struct inquiry_data data;
3089 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003090 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003091
3092 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3093
3094 if (!num_rsp)
3095 return;
3096
Andre Guedes1519cc12012-03-21 00:03:38 -03003097 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3098 return;
3099
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003100 hci_dev_lock(hdev);
3101
3102 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01003103 struct inquiry_info_with_rssi_and_pscan_mode *info;
3104 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003105
Johan Hedberge17acd42011-03-30 23:57:16 +03003106 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003107 bacpy(&data.bdaddr, &info->bdaddr);
3108 data.pscan_rep_mode = info->pscan_rep_mode;
3109 data.pscan_period_mode = info->pscan_period_mode;
3110 data.pscan_mode = info->pscan_mode;
3111 memcpy(data.dev_class, info->dev_class, 3);
3112 data.clock_offset = info->clock_offset;
3113 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003114 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003115
3116 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003117 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003118 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003119 info->dev_class, info->rssi,
3120 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003121 }
3122 } else {
3123 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
3124
Johan Hedberge17acd42011-03-30 23:57:16 +03003125 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003126 bacpy(&data.bdaddr, &info->bdaddr);
3127 data.pscan_rep_mode = info->pscan_rep_mode;
3128 data.pscan_period_mode = info->pscan_period_mode;
3129 data.pscan_mode = 0x00;
3130 memcpy(data.dev_class, info->dev_class, 3);
3131 data.clock_offset = info->clock_offset;
3132 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003133 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003134 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003135 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003136 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003137 info->dev_class, info->rssi,
3138 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003139 }
3140 }
3141
3142 hci_dev_unlock(hdev);
3143}
3144
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003145static void hci_remote_ext_features_evt(struct hci_dev *hdev,
3146 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003147{
Marcel Holtmann41a96212008-07-14 20:13:48 +02003148 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
3149 struct hci_conn *conn;
3150
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003151 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003152
Marcel Holtmann41a96212008-07-14 20:13:48 +02003153 hci_dev_lock(hdev);
3154
3155 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02003156 if (!conn)
3157 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003158
Johan Hedbergccd556f2010-11-10 17:11:51 +02003159 if (!ev->status && ev->page == 0x01) {
3160 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003161
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003162 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3163 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003164 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02003165
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003166 if (ev->features[0] & LMP_HOST_SSP)
Johan Hedberg58a681e2012-01-16 06:47:28 +02003167 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003168 }
3169
Johan Hedbergccd556f2010-11-10 17:11:51 +02003170 if (conn->state != BT_CONFIG)
3171 goto unlock;
3172
Johan Hedberg671267b2012-05-12 16:11:50 -03003173 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02003174 struct hci_cp_remote_name_req cp;
3175 memset(&cp, 0, sizeof(cp));
3176 bacpy(&cp.bdaddr, &conn->dst);
3177 cp.pscan_rep_mode = 0x02;
3178 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02003179 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3180 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003181 conn->dst_type, 0, NULL, 0,
3182 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02003183
Johan Hedberg127178d2010-11-18 22:22:29 +02003184 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02003185 conn->state = BT_CONNECTED;
3186 hci_proto_connect_cfm(conn, ev->status);
3187 hci_conn_put(conn);
3188 }
3189
3190unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02003191 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003192}
3193
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003194static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3195 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003196{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003197 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3198 struct hci_conn *conn;
3199
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003200 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003201
3202 hci_dev_lock(hdev);
3203
3204 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02003205 if (!conn) {
3206 if (ev->link_type == ESCO_LINK)
3207 goto unlock;
3208
3209 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3210 if (!conn)
3211 goto unlock;
3212
3213 conn->type = SCO_LINK;
3214 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003215
Marcel Holtmann732547f2009-04-19 19:14:14 +02003216 switch (ev->status) {
3217 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003218 conn->handle = __le16_to_cpu(ev->handle);
3219 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003220
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07003221 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003222 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02003223 break;
3224
Stephen Coe705e5712010-02-16 11:29:44 -05003225 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003226 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08003227 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003228 case 0x1f: /* Unspecified error */
3229 if (conn->out && conn->attempt < 2) {
3230 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3231 (hdev->esco_type & EDR_ESCO_MASK);
3232 hci_setup_sync(conn, conn->link->handle);
3233 goto unlock;
3234 }
3235 /* fall through */
3236
3237 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003238 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003239 break;
3240 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003241
3242 hci_proto_connect_cfm(conn, ev->status);
3243 if (ev->status)
3244 hci_conn_del(conn);
3245
3246unlock:
3247 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003248}
3249
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003250static void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003251{
3252 BT_DBG("%s", hdev->name);
3253}
3254
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003255static void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02003256{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003257 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02003258
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003259 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02003260}
3261
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003262static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3263 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003264{
3265 struct inquiry_data data;
3266 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3267 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303268 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003269
3270 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3271
3272 if (!num_rsp)
3273 return;
3274
Andre Guedes1519cc12012-03-21 00:03:38 -03003275 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3276 return;
3277
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003278 hci_dev_lock(hdev);
3279
Johan Hedberge17acd42011-03-30 23:57:16 +03003280 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003281 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003282
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003283 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003284 data.pscan_rep_mode = info->pscan_rep_mode;
3285 data.pscan_period_mode = info->pscan_period_mode;
3286 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003287 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003288 data.clock_offset = info->clock_offset;
3289 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003290 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003291
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003292 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003293 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003294 sizeof(info->data),
3295 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003296 else
3297 name_known = true;
3298
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003299 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003300 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303301 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003302 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003303 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303304 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003305 }
3306
3307 hci_dev_unlock(hdev);
3308}
3309
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003310static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3311 struct sk_buff *skb)
3312{
3313 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3314 struct hci_conn *conn;
3315
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003316 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003317 __le16_to_cpu(ev->handle));
3318
3319 hci_dev_lock(hdev);
3320
3321 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3322 if (!conn)
3323 goto unlock;
3324
3325 if (!ev->status)
3326 conn->sec_level = conn->pending_sec_level;
3327
3328 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3329
3330 if (ev->status && conn->state == BT_CONNECTED) {
3331 hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE);
3332 hci_conn_put(conn);
3333 goto unlock;
3334 }
3335
3336 if (conn->state == BT_CONFIG) {
3337 if (!ev->status)
3338 conn->state = BT_CONNECTED;
3339
3340 hci_proto_connect_cfm(conn, ev->status);
3341 hci_conn_put(conn);
3342 } else {
3343 hci_auth_cfm(conn, ev->status);
3344
3345 hci_conn_hold(conn);
3346 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
3347 hci_conn_put(conn);
3348 }
3349
3350unlock:
3351 hci_dev_unlock(hdev);
3352}
3353
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003354static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003355{
3356 /* If remote requests dedicated bonding follow that lead */
3357 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3358 /* If both remote and local IO capabilities allow MITM
3359 * protection then require it, otherwise don't */
3360 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3361 return 0x02;
3362 else
3363 return 0x03;
3364 }
3365
3366 /* If remote requests no-bonding follow that lead */
3367 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003368 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003369
3370 return conn->auth_type;
3371}
3372
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003373static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003374{
3375 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3376 struct hci_conn *conn;
3377
3378 BT_DBG("%s", hdev->name);
3379
3380 hci_dev_lock(hdev);
3381
3382 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003383 if (!conn)
3384 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003385
Johan Hedberg03b555e2011-01-04 15:40:05 +02003386 hci_conn_hold(conn);
3387
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003388 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003389 goto unlock;
3390
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003391 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003392 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003393 struct hci_cp_io_capability_reply cp;
3394
3395 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303396 /* Change the IO capability from KeyboardDisplay
3397 * to DisplayYesNo as it is not supported by BT spec. */
3398 cp.capability = (conn->io_capability == 0x04) ?
3399 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003400 conn->auth_type = hci_get_auth_req(conn);
3401 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003402
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003403 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3404 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003405 cp.oob_data = 0x01;
3406 else
3407 cp.oob_data = 0x00;
3408
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003409 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003410 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003411 } else {
3412 struct hci_cp_io_capability_neg_reply cp;
3413
3414 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003415 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003416
3417 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003418 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003419 }
3420
3421unlock:
3422 hci_dev_unlock(hdev);
3423}
3424
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003425static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003426{
3427 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3428 struct hci_conn *conn;
3429
3430 BT_DBG("%s", hdev->name);
3431
3432 hci_dev_lock(hdev);
3433
3434 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3435 if (!conn)
3436 goto unlock;
3437
Johan Hedberg03b555e2011-01-04 15:40:05 +02003438 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003439 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003440 if (ev->oob_data)
3441 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003442
3443unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003444 hci_dev_unlock(hdev);
3445}
3446
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003447static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3448 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003449{
3450 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003451 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003452 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003453
3454 BT_DBG("%s", hdev->name);
3455
3456 hci_dev_lock(hdev);
3457
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003458 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003459 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003460
Johan Hedberg7a828902011-04-28 11:28:53 -07003461 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3462 if (!conn)
3463 goto unlock;
3464
3465 loc_mitm = (conn->auth_type & 0x01);
3466 rem_mitm = (conn->remote_auth & 0x01);
3467
3468 /* If we require MITM but the remote device can't provide that
3469 * (it has NoInputNoOutput) then reject the confirmation
3470 * request. The only exception is when we're dedicated bonding
3471 * initiators (connect_cfm_cb set) since then we always have the MITM
3472 * bit set. */
3473 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3474 BT_DBG("Rejecting request: remote device can't provide MITM");
3475 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003476 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003477 goto unlock;
3478 }
3479
3480 /* If no side requires MITM protection; auto-accept */
3481 if ((!loc_mitm || conn->remote_cap == 0x03) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003482 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003483
3484 /* If we're not the initiators request authorization to
3485 * proceed from user space (mgmt_user_confirm with
3486 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003487 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003488 BT_DBG("Confirming auto-accept as acceptor");
3489 confirm_hint = 1;
3490 goto confirm;
3491 }
3492
Johan Hedberg9f616562011-04-28 11:28:54 -07003493 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003494 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003495
3496 if (hdev->auto_accept_delay > 0) {
3497 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3498 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3499 goto unlock;
3500 }
3501
Johan Hedberg7a828902011-04-28 11:28:53 -07003502 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003503 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003504 goto unlock;
3505 }
3506
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003507confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003508 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003509 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003510
3511unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003512 hci_dev_unlock(hdev);
3513}
3514
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003515static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3516 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003517{
3518 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3519
3520 BT_DBG("%s", hdev->name);
3521
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003522 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003523 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003524}
3525
Johan Hedberg92a25252012-09-06 18:39:26 +03003526static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3527 struct sk_buff *skb)
3528{
3529 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3530 struct hci_conn *conn;
3531
3532 BT_DBG("%s", hdev->name);
3533
3534 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3535 if (!conn)
3536 return;
3537
3538 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3539 conn->passkey_entered = 0;
3540
3541 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3542 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3543 conn->dst_type, conn->passkey_notify,
3544 conn->passkey_entered);
3545}
3546
3547static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3548{
3549 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3550 struct hci_conn *conn;
3551
3552 BT_DBG("%s", hdev->name);
3553
3554 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3555 if (!conn)
3556 return;
3557
3558 switch (ev->type) {
3559 case HCI_KEYPRESS_STARTED:
3560 conn->passkey_entered = 0;
3561 return;
3562
3563 case HCI_KEYPRESS_ENTERED:
3564 conn->passkey_entered++;
3565 break;
3566
3567 case HCI_KEYPRESS_ERASED:
3568 conn->passkey_entered--;
3569 break;
3570
3571 case HCI_KEYPRESS_CLEARED:
3572 conn->passkey_entered = 0;
3573 break;
3574
3575 case HCI_KEYPRESS_COMPLETED:
3576 return;
3577 }
3578
3579 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3580 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3581 conn->dst_type, conn->passkey_notify,
3582 conn->passkey_entered);
3583}
3584
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003585static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3586 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003587{
3588 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3589 struct hci_conn *conn;
3590
3591 BT_DBG("%s", hdev->name);
3592
3593 hci_dev_lock(hdev);
3594
3595 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003596 if (!conn)
3597 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003598
Johan Hedberg2a611692011-02-19 12:06:00 -03003599 /* To avoid duplicate auth_failed events to user space we check
3600 * the HCI_CONN_AUTH_PEND flag which will be set if we
3601 * initiated the authentication. A traditional auth_complete
3602 * event gets always produced as initiator and is also mapped to
3603 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003604 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003605 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003606 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003607
3608 hci_conn_put(conn);
3609
3610unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003611 hci_dev_unlock(hdev);
3612}
3613
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003614static void hci_remote_host_features_evt(struct hci_dev *hdev,
3615 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003616{
3617 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3618 struct inquiry_entry *ie;
3619
3620 BT_DBG("%s", hdev->name);
3621
3622 hci_dev_lock(hdev);
3623
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003624 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3625 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003626 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003627
3628 hci_dev_unlock(hdev);
3629}
3630
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003631static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3632 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003633{
3634 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3635 struct oob_data *data;
3636
3637 BT_DBG("%s", hdev->name);
3638
3639 hci_dev_lock(hdev);
3640
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003641 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003642 goto unlock;
3643
Szymon Janc2763eda2011-03-22 13:12:22 +01003644 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3645 if (data) {
3646 struct hci_cp_remote_oob_data_reply cp;
3647
3648 bacpy(&cp.bdaddr, &ev->bdaddr);
3649 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3650 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3651
3652 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003653 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003654 } else {
3655 struct hci_cp_remote_oob_data_neg_reply cp;
3656
3657 bacpy(&cp.bdaddr, &ev->bdaddr);
3658 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003659 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003660 }
3661
Szymon Jance1ba1f12011-04-06 13:01:59 +02003662unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003663 hci_dev_unlock(hdev);
3664}
3665
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003666static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3667 struct sk_buff *skb)
3668{
3669 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3670 struct hci_conn *hcon, *bredr_hcon;
3671
3672 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3673 ev->status);
3674
3675 hci_dev_lock(hdev);
3676
3677 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3678 if (!hcon) {
3679 hci_dev_unlock(hdev);
3680 return;
3681 }
3682
3683 if (ev->status) {
3684 hci_conn_del(hcon);
3685 hci_dev_unlock(hdev);
3686 return;
3687 }
3688
3689 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3690
3691 hcon->state = BT_CONNECTED;
3692 bacpy(&hcon->dst, &bredr_hcon->dst);
3693
3694 hci_conn_hold(hcon);
3695 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3696 hci_conn_put(hcon);
3697
3698 hci_conn_hold_device(hcon);
3699 hci_conn_add_sysfs(hcon);
3700
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003701 amp_physical_cfm(bredr_hcon, hcon);
3702
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003703 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003704}
3705
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003706static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3707{
3708 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3709 struct hci_conn *hcon;
3710 struct hci_chan *hchan;
3711 struct amp_mgr *mgr;
3712
3713 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3714 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3715 ev->status);
3716
3717 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3718 if (!hcon)
3719 return;
3720
3721 /* Create AMP hchan */
3722 hchan = hci_chan_create(hcon);
3723 if (!hchan)
3724 return;
3725
3726 hchan->handle = le16_to_cpu(ev->handle);
3727
3728 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3729
3730 mgr = hcon->amp_mgr;
3731 if (mgr && mgr->bredr_chan) {
3732 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3733
3734 l2cap_chan_lock(bredr_chan);
3735
3736 bredr_chan->conn->mtu = hdev->block_mtu;
3737 l2cap_logical_cfm(bredr_chan, hchan, 0);
3738 hci_conn_hold(hcon);
3739
3740 l2cap_chan_unlock(bredr_chan);
3741 }
3742}
3743
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003744static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3745 struct sk_buff *skb)
3746{
3747 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3748 struct hci_chan *hchan;
3749
3750 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3751 le16_to_cpu(ev->handle), ev->status);
3752
3753 if (ev->status)
3754 return;
3755
3756 hci_dev_lock(hdev);
3757
3758 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3759 if (!hchan)
3760 goto unlock;
3761
3762 amp_destroy_logical_link(hchan, ev->reason);
3763
3764unlock:
3765 hci_dev_unlock(hdev);
3766}
3767
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003768static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3769 struct sk_buff *skb)
3770{
3771 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3772 struct hci_conn *hcon;
3773
3774 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3775
3776 if (ev->status)
3777 return;
3778
3779 hci_dev_lock(hdev);
3780
3781 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3782 if (hcon) {
3783 hcon->state = BT_CLOSED;
3784 hci_conn_del(hcon);
3785 }
3786
3787 hci_dev_unlock(hdev);
3788}
3789
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003790static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003791{
3792 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3793 struct hci_conn *conn;
3794
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003795 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003796
3797 hci_dev_lock(hdev);
3798
Andre Guedesb47a09b2012-07-27 15:10:15 -03003799 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003800 if (!conn) {
3801 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3802 if (!conn) {
3803 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003804 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003805 }
Andre Guedes29b79882011-05-31 14:20:54 -03003806
3807 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003808
3809 if (ev->role == LE_CONN_ROLE_MASTER) {
3810 conn->out = true;
3811 conn->link_mode |= HCI_LM_MASTER;
3812 }
Ville Tervob62f3282011-02-10 22:38:50 -03003813 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003814
Andre Guedescd17dec2012-07-27 15:10:16 -03003815 if (ev->status) {
3816 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3817 conn->dst_type, ev->status);
3818 hci_proto_connect_cfm(conn, ev->status);
3819 conn->state = BT_CLOSED;
3820 hci_conn_del(conn);
3821 goto unlock;
3822 }
3823
Johan Hedbergb644ba32012-01-17 21:48:47 +02003824 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3825 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003826 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003827
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003828 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003829 conn->handle = __le16_to_cpu(ev->handle);
3830 conn->state = BT_CONNECTED;
3831
3832 hci_conn_hold_device(conn);
3833 hci_conn_add_sysfs(conn);
3834
3835 hci_proto_connect_cfm(conn, ev->status);
3836
3837unlock:
3838 hci_dev_unlock(hdev);
3839}
3840
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003841static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003842{
Andre Guedese95beb42011-09-26 20:48:35 -03003843 u8 num_reports = skb->data[0];
3844 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003845 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003846
3847 hci_dev_lock(hdev);
3848
Andre Guedese95beb42011-09-26 20:48:35 -03003849 while (num_reports--) {
3850 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003851
Andre Guedes3c9e9192012-01-10 18:20:50 -03003852 rssi = ev->data[ev->length];
3853 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003854 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003855
Andre Guedese95beb42011-09-26 20:48:35 -03003856 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003857 }
3858
3859 hci_dev_unlock(hdev);
3860}
3861
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003862static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003863{
3864 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3865 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003866 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003867 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003868 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003869
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003870 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003871
3872 hci_dev_lock(hdev);
3873
3874 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003875 if (conn == NULL)
3876 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003877
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003878 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3879 if (ltk == NULL)
3880 goto not_found;
3881
3882 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003883 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003884
3885 if (ltk->authenticated)
3886 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003887
3888 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3889
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003890 if (ltk->type & HCI_SMP_STK) {
3891 list_del(&ltk->list);
3892 kfree(ltk);
3893 }
3894
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003895 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003896
3897 return;
3898
3899not_found:
3900 neg.handle = ev->handle;
3901 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3902 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003903}
3904
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003905static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003906{
3907 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3908
3909 skb_pull(skb, sizeof(*le_ev));
3910
3911 switch (le_ev->subevent) {
3912 case HCI_EV_LE_CONN_COMPLETE:
3913 hci_le_conn_complete_evt(hdev, skb);
3914 break;
3915
Andre Guedes9aa04c92011-05-26 16:23:51 -03003916 case HCI_EV_LE_ADVERTISING_REPORT:
3917 hci_le_adv_report_evt(hdev, skb);
3918 break;
3919
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003920 case HCI_EV_LE_LTK_REQ:
3921 hci_le_ltk_request_evt(hdev, skb);
3922 break;
3923
Ville Tervofcd89c02011-02-10 22:38:47 -03003924 default:
3925 break;
3926 }
3927}
3928
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003929static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3930{
3931 struct hci_ev_channel_selected *ev = (void *) skb->data;
3932 struct hci_conn *hcon;
3933
3934 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3935
3936 skb_pull(skb, sizeof(*ev));
3937
3938 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3939 if (!hcon)
3940 return;
3941
3942 amp_read_loc_assoc_final_data(hdev, hcon);
3943}
3944
Linus Torvalds1da177e2005-04-16 15:20:36 -07003945void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3946{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003947 struct hci_event_hdr *hdr = (void *) skb->data;
3948 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003949
3950 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3951
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003952 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003953 case HCI_EV_INQUIRY_COMPLETE:
3954 hci_inquiry_complete_evt(hdev, skb);
3955 break;
3956
3957 case HCI_EV_INQUIRY_RESULT:
3958 hci_inquiry_result_evt(hdev, skb);
3959 break;
3960
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003961 case HCI_EV_CONN_COMPLETE:
3962 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003963 break;
3964
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965 case HCI_EV_CONN_REQUEST:
3966 hci_conn_request_evt(hdev, skb);
3967 break;
3968
Linus Torvalds1da177e2005-04-16 15:20:36 -07003969 case HCI_EV_DISCONN_COMPLETE:
3970 hci_disconn_complete_evt(hdev, skb);
3971 break;
3972
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973 case HCI_EV_AUTH_COMPLETE:
3974 hci_auth_complete_evt(hdev, skb);
3975 break;
3976
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003977 case HCI_EV_REMOTE_NAME:
3978 hci_remote_name_evt(hdev, skb);
3979 break;
3980
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981 case HCI_EV_ENCRYPT_CHANGE:
3982 hci_encrypt_change_evt(hdev, skb);
3983 break;
3984
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003985 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3986 hci_change_link_key_complete_evt(hdev, skb);
3987 break;
3988
3989 case HCI_EV_REMOTE_FEATURES:
3990 hci_remote_features_evt(hdev, skb);
3991 break;
3992
3993 case HCI_EV_REMOTE_VERSION:
3994 hci_remote_version_evt(hdev, skb);
3995 break;
3996
3997 case HCI_EV_QOS_SETUP_COMPLETE:
3998 hci_qos_setup_complete_evt(hdev, skb);
3999 break;
4000
4001 case HCI_EV_CMD_COMPLETE:
4002 hci_cmd_complete_evt(hdev, skb);
4003 break;
4004
4005 case HCI_EV_CMD_STATUS:
4006 hci_cmd_status_evt(hdev, skb);
4007 break;
4008
4009 case HCI_EV_ROLE_CHANGE:
4010 hci_role_change_evt(hdev, skb);
4011 break;
4012
4013 case HCI_EV_NUM_COMP_PKTS:
4014 hci_num_comp_pkts_evt(hdev, skb);
4015 break;
4016
4017 case HCI_EV_MODE_CHANGE:
4018 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019 break;
4020
4021 case HCI_EV_PIN_CODE_REQ:
4022 hci_pin_code_request_evt(hdev, skb);
4023 break;
4024
4025 case HCI_EV_LINK_KEY_REQ:
4026 hci_link_key_request_evt(hdev, skb);
4027 break;
4028
4029 case HCI_EV_LINK_KEY_NOTIFY:
4030 hci_link_key_notify_evt(hdev, skb);
4031 break;
4032
4033 case HCI_EV_CLOCK_OFFSET:
4034 hci_clock_offset_evt(hdev, skb);
4035 break;
4036
Marcel Holtmanna8746412008-07-14 20:13:46 +02004037 case HCI_EV_PKT_TYPE_CHANGE:
4038 hci_pkt_type_change_evt(hdev, skb);
4039 break;
4040
Marcel Holtmann85a1e932005-08-09 20:28:02 -07004041 case HCI_EV_PSCAN_REP_MODE:
4042 hci_pscan_rep_mode_evt(hdev, skb);
4043 break;
4044
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004045 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
4046 hci_inquiry_result_with_rssi_evt(hdev, skb);
4047 break;
4048
4049 case HCI_EV_REMOTE_EXT_FEATURES:
4050 hci_remote_ext_features_evt(hdev, skb);
4051 break;
4052
4053 case HCI_EV_SYNC_CONN_COMPLETE:
4054 hci_sync_conn_complete_evt(hdev, skb);
4055 break;
4056
4057 case HCI_EV_SYNC_CONN_CHANGED:
4058 hci_sync_conn_changed_evt(hdev, skb);
4059 break;
4060
Marcel Holtmann04837f62006-07-03 10:02:33 +02004061 case HCI_EV_SNIFF_SUBRATE:
4062 hci_sniff_subrate_evt(hdev, skb);
4063 break;
4064
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004065 case HCI_EV_EXTENDED_INQUIRY_RESULT:
4066 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004067 break;
4068
Johan Hedberg1c2e0042012-06-08 23:31:13 +08004069 case HCI_EV_KEY_REFRESH_COMPLETE:
4070 hci_key_refresh_complete_evt(hdev, skb);
4071 break;
4072
Marcel Holtmann04936842008-07-14 20:13:48 +02004073 case HCI_EV_IO_CAPA_REQUEST:
4074 hci_io_capa_request_evt(hdev, skb);
4075 break;
4076
Johan Hedberg03b555e2011-01-04 15:40:05 +02004077 case HCI_EV_IO_CAPA_REPLY:
4078 hci_io_capa_reply_evt(hdev, skb);
4079 break;
4080
Johan Hedberga5c29682011-02-19 12:05:57 -03004081 case HCI_EV_USER_CONFIRM_REQUEST:
4082 hci_user_confirm_request_evt(hdev, skb);
4083 break;
4084
Brian Gix1143d452011-11-23 08:28:34 -08004085 case HCI_EV_USER_PASSKEY_REQUEST:
4086 hci_user_passkey_request_evt(hdev, skb);
4087 break;
4088
Johan Hedberg92a25252012-09-06 18:39:26 +03004089 case HCI_EV_USER_PASSKEY_NOTIFY:
4090 hci_user_passkey_notify_evt(hdev, skb);
4091 break;
4092
4093 case HCI_EV_KEYPRESS_NOTIFY:
4094 hci_keypress_notify_evt(hdev, skb);
4095 break;
4096
Marcel Holtmann04936842008-07-14 20:13:48 +02004097 case HCI_EV_SIMPLE_PAIR_COMPLETE:
4098 hci_simple_pair_complete_evt(hdev, skb);
4099 break;
4100
Marcel Holtmann41a96212008-07-14 20:13:48 +02004101 case HCI_EV_REMOTE_HOST_FEATURES:
4102 hci_remote_host_features_evt(hdev, skb);
4103 break;
4104
Ville Tervofcd89c02011-02-10 22:38:47 -03004105 case HCI_EV_LE_META:
4106 hci_le_meta_evt(hdev, skb);
4107 break;
4108
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004109 case HCI_EV_CHANNEL_SELECTED:
4110 hci_chan_selected_evt(hdev, skb);
4111 break;
4112
Szymon Janc2763eda2011-03-22 13:12:22 +01004113 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
4114 hci_remote_oob_data_request_evt(hdev, skb);
4115 break;
4116
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03004117 case HCI_EV_PHY_LINK_COMPLETE:
4118 hci_phy_link_complete_evt(hdev, skb);
4119 break;
4120
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004121 case HCI_EV_LOGICAL_LINK_COMPLETE:
4122 hci_loglink_complete_evt(hdev, skb);
4123 break;
4124
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02004125 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
4126 hci_disconn_loglink_complete_evt(hdev, skb);
4127 break;
4128
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02004129 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
4130 hci_disconn_phylink_complete_evt(hdev, skb);
4131 break;
4132
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02004133 case HCI_EV_NUM_COMP_BLOCKS:
4134 hci_num_comp_blocks_evt(hdev, skb);
4135 break;
4136
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004137 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004138 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004139 break;
4140 }
4141
4142 kfree_skb(skb);
4143 hdev->stat.evt_rx++;
4144}