blob: ed4ecd930a715394f8bd4565e735ff3ccc1dbe9c [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <asm/unaligned.h>
28
29#include <net/bluetooth/bluetooth.h>
30#include <net/bluetooth/hci_core.h>
Mikel Astizf0d6a0e2012-08-09 09:52:30 +020031#include <net/bluetooth/mgmt.h>
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +030032#include <net/bluetooth/a2mp.h>
Andrei Emeltchenko903e4542012-09-27 17:26:09 +030033#include <net/bluetooth/amp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Linus Torvalds1da177e2005-04-16 15:20:36 -070035/* Handle HCI Event packets */
36
Marcel Holtmanna9de9242007-10-20 13:33:56 +020037static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070038{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020039 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030041 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Andre Guedese6d465c2011-11-09 17:14:26 -030043 if (status) {
44 hci_dev_lock(hdev);
45 mgmt_stop_discovery_failed(hdev, status);
46 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020047 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030048 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Andre Guedes89352e72011-11-04 14:16:53 -030050 clear_bit(HCI_INQUIRY, &hdev->flags);
51
Johan Hedberg56e5cb82011-11-08 20:40:16 +020052 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020053 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020054 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010055
Johan Hedberg9238f362013-03-05 20:37:48 +020056 hci_req_cmd_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010057
Marcel Holtmanna9de9242007-10-20 13:33:56 +020058 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070059}
60
Andre Guedes4d934832012-03-21 00:03:35 -030061static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
62{
63 __u8 status = *((__u8 *) skb->data);
64
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030065 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030066
67 if (status)
68 return;
69
70 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030071}
72
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020075 __u8 status = *((__u8 *) skb->data);
76
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030077 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020078
79 if (status)
80 return;
81
Andre Guedesae854a72012-03-21 00:03:36 -030082 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
83
Marcel Holtmanna9de9242007-10-20 13:33:56 +020084 hci_conn_check_pending(hdev);
85}
86
Gustavo Padovan807deac2012-05-17 00:36:24 -030087static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
88 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020089{
90 BT_DBG("%s", hdev->name);
91}
92
93static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
94{
95 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030098 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 if (rp->status)
101 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200103 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
106 if (conn) {
107 if (rp->role)
108 conn->link_mode &= ~HCI_LM_MASTER;
109 else
110 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200112
113 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114}
115
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200116static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
117{
118 struct hci_rp_read_link_policy *rp = (void *) skb->data;
119 struct hci_conn *conn;
120
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300121 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200122
123 if (rp->status)
124 return;
125
126 hci_dev_lock(hdev);
127
128 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
129 if (conn)
130 conn->link_policy = __le16_to_cpu(rp->policy);
131
132 hci_dev_unlock(hdev);
133}
134
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200137 struct hci_rp_write_link_policy *rp = (void *) skb->data;
138 struct hci_conn *conn;
139 void *sent;
140
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300141 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200142
143 if (rp->status)
144 return;
145
146 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
147 if (!sent)
148 return;
149
150 hci_dev_lock(hdev);
151
152 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200153 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700154 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200155
156 hci_dev_unlock(hdev);
157}
158
Gustavo Padovan807deac2012-05-17 00:36:24 -0300159static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
160 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200161{
162 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
163
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300164 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200165
166 if (rp->status)
167 return;
168
169 hdev->link_policy = __le16_to_cpu(rp->policy);
170}
171
Gustavo Padovan807deac2012-05-17 00:36:24 -0300172static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
173 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200174{
175 __u8 status = *((__u8 *) skb->data);
176 void *sent;
177
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300178 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200179
180 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
181 if (!sent)
182 return;
183
184 if (!status)
185 hdev->link_policy = get_unaligned_le16(sent);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200186}
187
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200188static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
189{
190 __u8 status = *((__u8 *) skb->data);
191
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300192 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200193
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300194 clear_bit(HCI_RESET, &hdev->flags);
195
Johan Hedberga297e972012-02-21 17:55:47 +0200196 /* Reset all non-persistent flags */
Johan Hedberg2cc6fb02013-03-15 17:06:57 -0500197 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
Andre Guedes69775ff2012-02-23 16:50:05 +0200198
199 hdev->discovery.state = DISCOVERY_STOPPED;
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100200 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
201 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100202
203 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
204 hdev->adv_data_len = 0;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200205}
206
207static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
208{
209 __u8 status = *((__u8 *) skb->data);
210 void *sent;
211
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300212 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200213
214 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
215 if (!sent)
216 return;
217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 hci_dev_lock(hdev);
219
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200220 if (test_bit(HCI_MGMT, &hdev->dev_flags))
221 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200222 else if (!status)
223 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200224
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200225 hci_dev_unlock(hdev);
Johan Hedberg3159d382012-02-24 13:47:56 +0200226
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100227 if (!status && !test_bit(HCI_INIT, &hdev->flags))
228 hci_update_ad(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200229}
230
231static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
232{
233 struct hci_rp_read_local_name *rp = (void *) skb->data;
234
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300235 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200236
237 if (rp->status)
238 return;
239
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200240 if (test_bit(HCI_SETUP, &hdev->dev_flags))
241 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200242}
243
244static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
245{
246 __u8 status = *((__u8 *) skb->data);
247 void *sent;
248
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300249 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200250
251 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
252 if (!sent)
253 return;
254
255 if (!status) {
256 __u8 param = *((__u8 *) sent);
257
258 if (param == AUTH_ENABLED)
259 set_bit(HCI_AUTH, &hdev->flags);
260 else
261 clear_bit(HCI_AUTH, &hdev->flags);
262 }
263
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200264 if (test_bit(HCI_MGMT, &hdev->dev_flags))
265 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200266}
267
268static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
269{
270 __u8 status = *((__u8 *) skb->data);
271 void *sent;
272
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300273 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200274
275 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
276 if (!sent)
277 return;
278
279 if (!status) {
280 __u8 param = *((__u8 *) sent);
281
282 if (param)
283 set_bit(HCI_ENCRYPT, &hdev->flags);
284 else
285 clear_bit(HCI_ENCRYPT, &hdev->flags);
286 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200287}
288
289static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
290{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200291 __u8 param, status = *((__u8 *) skb->data);
292 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200293 void *sent;
294
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300295 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200296
297 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
298 if (!sent)
299 return;
300
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200301 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200302
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200303 hci_dev_lock(hdev);
304
Mikel Astizfa1bd912012-08-09 09:52:29 +0200305 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200306 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200307 hdev->discov_timeout = 0;
308 goto done;
309 }
310
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200311 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
312 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200313
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200314 if (param & SCAN_INQUIRY) {
315 set_bit(HCI_ISCAN, &hdev->flags);
316 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200317 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200318 if (hdev->discov_timeout > 0) {
319 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
320 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300321 to);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200322 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200324 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200325
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200326 if (param & SCAN_PAGE) {
327 set_bit(HCI_PSCAN, &hdev->flags);
328 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200329 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200330 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200331 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200332
333done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200334 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200335}
336
337static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
338{
339 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
340
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300341 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200342
343 if (rp->status)
344 return;
345
346 memcpy(hdev->dev_class, rp->dev_class, 3);
347
348 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300349 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200350}
351
352static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
353{
354 __u8 status = *((__u8 *) skb->data);
355 void *sent;
356
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300357 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200358
359 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
360 if (!sent)
361 return;
362
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100363 hci_dev_lock(hdev);
364
365 if (status == 0)
366 memcpy(hdev->dev_class, sent, 3);
367
368 if (test_bit(HCI_MGMT, &hdev->dev_flags))
369 mgmt_set_class_of_dev_complete(hdev, sent, status);
370
371 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200372}
373
374static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
375{
376 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200378
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300379 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200380
381 if (rp->status)
382 return;
383
384 setting = __le16_to_cpu(rp->voice_setting);
385
Marcel Holtmannf383f272008-07-14 20:13:47 +0200386 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200387 return;
388
389 hdev->voice_setting = setting;
390
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300391 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200393 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200394 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200395}
396
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300397static void hci_cc_write_voice_setting(struct hci_dev *hdev,
398 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200399{
400 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200401 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 void *sent;
403
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300404 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405
Marcel Holtmannf383f272008-07-14 20:13:47 +0200406 if (status)
407 return;
408
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200409 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
410 if (!sent)
411 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
Marcel Holtmannf383f272008-07-14 20:13:47 +0200413 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Marcel Holtmannf383f272008-07-14 20:13:47 +0200415 if (hdev->voice_setting == setting)
416 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
Marcel Holtmannf383f272008-07-14 20:13:47 +0200418 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300420 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200421
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200422 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200423 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424}
425
Marcel Holtmann333140b2008-07-14 20:13:48 +0200426static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
427{
428 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300429 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200430
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300431 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200432
Marcel Holtmann333140b2008-07-14 20:13:48 +0200433 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
434 if (!sent)
435 return;
436
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300437 if (!status) {
438 if (sent->mode)
439 hdev->host_features[0] |= LMP_HOST_SSP;
440 else
441 hdev->host_features[0] &= ~LMP_HOST_SSP;
442 }
443
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200444 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300445 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200446 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300447 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200448 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
449 else
450 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
451 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200452}
453
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200454static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
455{
456 struct hci_rp_read_local_version *rp = (void *) skb->data;
457
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300458 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200459
460 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200461 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200462
463 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200464 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200465 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200466 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200467 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200468
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300469 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300470 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200471}
472
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300473static void hci_cc_read_local_commands(struct hci_dev *hdev,
474 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200475{
476 struct hci_rp_read_local_commands *rp = (void *) skb->data;
477
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300478 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200479
Johan Hedberg2177bab2013-03-05 20:37:43 +0200480 if (!rp->status)
481 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200482}
483
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300484static void hci_cc_read_local_features(struct hci_dev *hdev,
485 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200486{
487 struct hci_rp_read_local_features *rp = (void *) skb->data;
488
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300489 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200490
491 if (rp->status)
492 return;
493
494 memcpy(hdev->features, rp->features, 8);
495
496 /* Adjust default settings according to features
497 * supported by device. */
498
499 if (hdev->features[0] & LMP_3SLOT)
500 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
501
502 if (hdev->features[0] & LMP_5SLOT)
503 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
504
505 if (hdev->features[1] & LMP_HV2) {
506 hdev->pkt_type |= (HCI_HV2);
507 hdev->esco_type |= (ESCO_HV2);
508 }
509
510 if (hdev->features[1] & LMP_HV3) {
511 hdev->pkt_type |= (HCI_HV3);
512 hdev->esco_type |= (ESCO_HV3);
513 }
514
Andre Guedes45db810f2012-07-24 15:03:49 -0300515 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200516 hdev->esco_type |= (ESCO_EV3);
517
518 if (hdev->features[4] & LMP_EV4)
519 hdev->esco_type |= (ESCO_EV4);
520
521 if (hdev->features[4] & LMP_EV5)
522 hdev->esco_type |= (ESCO_EV5);
523
Marcel Holtmannefc76882009-02-06 09:13:37 +0100524 if (hdev->features[5] & LMP_EDR_ESCO_2M)
525 hdev->esco_type |= (ESCO_2EV3);
526
527 if (hdev->features[5] & LMP_EDR_ESCO_3M)
528 hdev->esco_type |= (ESCO_3EV3);
529
530 if (hdev->features[5] & LMP_EDR_3S_ESCO)
531 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
532
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200533 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300534 hdev->features[0], hdev->features[1],
535 hdev->features[2], hdev->features[3],
536 hdev->features[4], hdev->features[5],
537 hdev->features[6], hdev->features[7]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200538}
539
Andre Guedes971e3a42011-06-30 19:20:52 -0300540static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300541 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300542{
543 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
544
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300545 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300546
547 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200548 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300549
Andre Guedesb5b32b62011-12-30 10:34:04 -0300550 switch (rp->page) {
551 case 0:
552 memcpy(hdev->features, rp->features, 8);
553 break;
554 case 1:
555 memcpy(hdev->host_features, rp->features, 8);
556 break;
557 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300558}
559
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200560static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300561 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200562{
563 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
564
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300565 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200566
Johan Hedberg42c6b122013-03-05 20:37:49 +0200567 if (!rp->status)
568 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200569}
570
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200571static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
572{
573 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
574
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300575 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200576
577 if (rp->status)
578 return;
579
580 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
581 hdev->sco_mtu = rp->sco_mtu;
582 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
583 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
584
585 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
586 hdev->sco_mtu = 64;
587 hdev->sco_pkts = 8;
588 }
589
590 hdev->acl_cnt = hdev->acl_pkts;
591 hdev->sco_cnt = hdev->sco_pkts;
592
Gustavo Padovan807deac2012-05-17 00:36:24 -0300593 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
594 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200595}
596
597static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
598{
599 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
600
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300601 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200602
603 if (!rp->status)
604 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200605}
606
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200607static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300608 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200609{
610 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
611
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300612 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200613
614 if (rp->status)
615 return;
616
617 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
618 hdev->block_len = __le16_to_cpu(rp->block_len);
619 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
620
621 hdev->block_cnt = hdev->num_blocks;
622
623 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300624 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200625}
626
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300627static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300628 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300629{
630 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
631
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300632 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300633
634 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300635 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300636
637 hdev->amp_status = rp->amp_status;
638 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
639 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
640 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
641 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
642 hdev->amp_type = rp->amp_type;
643 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
644 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
645 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
646 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
647
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300648a2mp_rsp:
649 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300650}
651
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300652static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
653 struct sk_buff *skb)
654{
655 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
656 struct amp_assoc *assoc = &hdev->loc_assoc;
657 size_t rem_len, frag_len;
658
659 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
660
661 if (rp->status)
662 goto a2mp_rsp;
663
664 frag_len = skb->len - sizeof(*rp);
665 rem_len = __le16_to_cpu(rp->rem_len);
666
667 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300668 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300669
670 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
671 assoc->offset += frag_len;
672
673 /* Read other fragments */
674 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
675
676 return;
677 }
678
679 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
680 assoc->len = assoc->offset + rem_len;
681 assoc->offset = 0;
682
683a2mp_rsp:
684 /* Send A2MP Rsp when all fragments are received */
685 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300686 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300687}
688
Johan Hedbergd5859e22011-01-25 01:19:58 +0200689static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300690 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200691{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700692 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200693
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300694 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200695
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700696 if (!rp->status)
697 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200698}
699
Johan Hedberg980e1a52011-01-22 06:10:07 +0200700static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
701{
702 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
703 struct hci_cp_pin_code_reply *cp;
704 struct hci_conn *conn;
705
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300706 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200707
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200708 hci_dev_lock(hdev);
709
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200710 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200711 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200712
Mikel Astizfa1bd912012-08-09 09:52:29 +0200713 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200714 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200715
716 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
717 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200718 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200719
720 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
721 if (conn)
722 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200723
724unlock:
725 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200726}
727
728static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
729{
730 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
731
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300732 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200733
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200734 hci_dev_lock(hdev);
735
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200736 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200737 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300738 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200739
740 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200741}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200742
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300743static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
744 struct sk_buff *skb)
745{
746 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
747
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300748 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300749
750 if (rp->status)
751 return;
752
753 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
754 hdev->le_pkts = rp->le_max_pkt;
755
756 hdev->le_cnt = hdev->le_pkts;
757
758 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300759}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200760
Johan Hedberg60e77322013-01-22 14:01:59 +0200761static void hci_cc_le_read_local_features(struct hci_dev *hdev,
762 struct sk_buff *skb)
763{
764 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
765
766 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
767
768 if (!rp->status)
769 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200770}
771
Johan Hedberg8fa19092012-10-19 20:57:49 +0300772static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
773 struct sk_buff *skb)
774{
775 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
776
777 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
778
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100779 if (!rp->status) {
Johan Hedberg8fa19092012-10-19 20:57:49 +0300780 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100781 if (!test_bit(HCI_INIT, &hdev->flags))
782 hci_update_ad(hdev);
783 }
Johan Hedberg8fa19092012-10-19 20:57:49 +0300784}
785
Johan Hedberga5c29682011-02-19 12:05:57 -0300786static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
787{
788 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
789
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300790 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300791
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200792 hci_dev_lock(hdev);
793
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200794 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300795 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
796 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200797
798 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300799}
800
801static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300802 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300803{
804 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
805
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300806 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300807
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200808 hci_dev_lock(hdev);
809
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200810 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200811 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300812 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200813
814 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300815}
816
Brian Gix1143d452011-11-23 08:28:34 -0800817static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
818{
819 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
820
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300821 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800822
823 hci_dev_lock(hdev);
824
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200825 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200826 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300827 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800828
829 hci_dev_unlock(hdev);
830}
831
832static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300833 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800834{
835 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
836
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300837 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800838
839 hci_dev_lock(hdev);
840
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200841 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800842 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300843 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800844
845 hci_dev_unlock(hdev);
846}
847
Szymon Jancc35938b2011-03-22 13:12:21 +0100848static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300849 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100850{
851 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
852
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300853 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100854
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200855 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200856 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100857 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200858 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100859}
860
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100861static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
862{
863 __u8 *sent, status = *((__u8 *) skb->data);
864
865 BT_DBG("%s status 0x%2.2x", hdev->name, status);
866
867 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
868 if (!sent)
869 return;
870
871 hci_dev_lock(hdev);
872
873 if (!status) {
874 if (*sent)
875 set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
876 else
877 clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
878 }
879
880 hci_dev_unlock(hdev);
881
882 if (!test_bit(HCI_INIT, &hdev->flags))
883 hci_update_ad(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100884}
885
Andre Guedes07f7fa52011-12-02 21:13:31 +0900886static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
887{
888 __u8 status = *((__u8 *) skb->data);
889
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300890 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300891
Andre Guedes3fd24152012-02-03 17:48:01 -0300892 if (status) {
893 hci_dev_lock(hdev);
894 mgmt_start_discovery_failed(hdev, status);
895 hci_dev_unlock(hdev);
896 return;
897 }
Andre Guedes07f7fa52011-12-02 21:13:31 +0900898}
899
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300900static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300901 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300902{
903 struct hci_cp_le_set_scan_enable *cp;
904 __u8 status = *((__u8 *) skb->data);
905
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300906 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300907
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300908 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
909 if (!cp)
910 return;
911
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200912 switch (cp->enable) {
913 case LE_SCANNING_ENABLED:
Andre Guedes3fd24152012-02-03 17:48:01 -0300914 if (status) {
915 hci_dev_lock(hdev);
916 mgmt_start_discovery_failed(hdev, status);
917 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300918 return;
Andre Guedes3fd24152012-02-03 17:48:01 -0300919 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300920
Andre Guedesd23264a2011-11-25 20:53:38 -0300921 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
922
Andre Guedesa8f13c82011-09-09 18:56:24 -0300923 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -0300924 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -0300925 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200926 break;
927
928 case LE_SCANNING_DISABLED:
Andre Guedesc9ecc482012-03-15 16:52:08 -0300929 if (status) {
930 hci_dev_lock(hdev);
931 mgmt_stop_discovery_failed(hdev, status);
932 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300933 return;
Andre Guedesc9ecc482012-03-15 16:52:08 -0300934 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300935
Andre Guedesd23264a2011-11-25 20:53:38 -0300936 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
937
Andre Guedesbc3dd332012-03-06 19:37:06 -0300938 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
939 hdev->discovery.state == DISCOVERY_FINDING) {
Andre Guedes5e0452c2012-02-17 20:39:38 -0300940 mgmt_interleaved_discovery(hdev);
941 } else {
942 hci_dev_lock(hdev);
943 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
944 hci_dev_unlock(hdev);
945 }
946
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200947 break;
948
949 default:
950 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
951 break;
Andre Guedes35815082011-05-26 16:23:53 -0300952 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300953}
954
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200955static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
956 struct sk_buff *skb)
957{
958 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
959
960 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
961
962 if (!rp->status)
963 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200964}
965
Johan Hedberg9b008c02013-01-22 14:02:01 +0200966static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
967 struct sk_buff *skb)
968{
969 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
970
971 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
972
973 if (!rp->status)
974 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +0200975}
976
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300977static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
978 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -0300979{
Johan Hedberg06199cf2012-02-22 16:37:11 +0200980 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -0300981 __u8 status = *((__u8 *) skb->data);
982
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300983 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -0300984
Johan Hedberg06199cf2012-02-22 16:37:11 +0200985 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +0200986 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -0300987 return;
988
Johan Hedberg8f984df2012-02-28 01:07:22 +0200989 if (!status) {
990 if (sent->le)
991 hdev->host_features[0] |= LMP_HOST_LE;
992 else
993 hdev->host_features[0] &= ~LMP_HOST_LE;
Johan Hedberg53b2caa2012-10-24 21:11:59 +0300994
995 if (sent->simul)
996 hdev->host_features[0] |= LMP_HOST_LE_BREDR;
997 else
998 hdev->host_features[0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +0200999 }
1000
1001 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001002 !test_bit(HCI_INIT, &hdev->flags))
Johan Hedberg8f984df2012-02-28 01:07:22 +02001003 mgmt_le_enable_complete(hdev, sent->le, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001004}
1005
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001006static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1007 struct sk_buff *skb)
1008{
1009 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1010
1011 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1012 hdev->name, rp->status, rp->phy_handle);
1013
1014 if (rp->status)
1015 return;
1016
1017 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1018}
1019
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001020static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001021{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001022 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001023
1024 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001025 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001026 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001027 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001028 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001029 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001030 return;
1031 }
1032
Andre Guedes89352e72011-11-04 14:16:53 -03001033 set_bit(HCI_INQUIRY, &hdev->flags);
1034
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001035 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001036 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001037 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001038}
1039
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001040static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001042 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001045 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001046
1047 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 if (!cp)
1049 return;
1050
1051 hci_dev_lock(hdev);
1052
1053 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1054
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001055 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056
1057 if (status) {
1058 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001059 if (status != 0x0c || conn->attempt > 2) {
1060 conn->state = BT_CLOSED;
1061 hci_proto_connect_cfm(conn, status);
1062 hci_conn_del(conn);
1063 } else
1064 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 }
1066 } else {
1067 if (!conn) {
1068 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1069 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001070 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 conn->link_mode |= HCI_LM_MASTER;
1072 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001073 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 }
1075 }
1076
1077 hci_dev_unlock(hdev);
1078}
1079
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001080static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001082 struct hci_cp_add_sco *cp;
1083 struct hci_conn *acl, *sco;
1084 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001086 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001087
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001088 if (!status)
1089 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001091 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1092 if (!cp)
1093 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001095 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001097 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001098
1099 hci_dev_lock(hdev);
1100
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001101 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001102 if (acl) {
1103 sco = acl->link;
1104 if (sco) {
1105 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001106
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001107 hci_proto_connect_cfm(sco, status);
1108 hci_conn_del(sco);
1109 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001110 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001111
1112 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113}
1114
Marcel Holtmannf8558552008-07-14 20:13:49 +02001115static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1116{
1117 struct hci_cp_auth_requested *cp;
1118 struct hci_conn *conn;
1119
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001120 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001121
1122 if (!status)
1123 return;
1124
1125 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1126 if (!cp)
1127 return;
1128
1129 hci_dev_lock(hdev);
1130
1131 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1132 if (conn) {
1133 if (conn->state == BT_CONFIG) {
1134 hci_proto_connect_cfm(conn, status);
1135 hci_conn_put(conn);
1136 }
1137 }
1138
1139 hci_dev_unlock(hdev);
1140}
1141
1142static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1143{
1144 struct hci_cp_set_conn_encrypt *cp;
1145 struct hci_conn *conn;
1146
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001147 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001148
1149 if (!status)
1150 return;
1151
1152 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1153 if (!cp)
1154 return;
1155
1156 hci_dev_lock(hdev);
1157
1158 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1159 if (conn) {
1160 if (conn->state == BT_CONFIG) {
1161 hci_proto_connect_cfm(conn, status);
1162 hci_conn_put(conn);
1163 }
1164 }
1165
1166 hci_dev_unlock(hdev);
1167}
1168
Johan Hedberg127178d2010-11-18 22:22:29 +02001169static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001170 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001171{
Johan Hedberg392599b2010-11-18 22:22:28 +02001172 if (conn->state != BT_CONFIG || !conn->out)
1173 return 0;
1174
Johan Hedberg765c2a92011-01-19 12:06:52 +05301175 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001176 return 0;
1177
1178 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001179 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001180 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1181 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001182 return 0;
1183
Johan Hedberg392599b2010-11-18 22:22:28 +02001184 return 1;
1185}
1186
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001187static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001188 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001189{
1190 struct hci_cp_remote_name_req cp;
1191
1192 memset(&cp, 0, sizeof(cp));
1193
1194 bacpy(&cp.bdaddr, &e->data.bdaddr);
1195 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1196 cp.pscan_mode = e->data.pscan_mode;
1197 cp.clock_offset = e->data.clock_offset;
1198
1199 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1200}
1201
Johan Hedbergb644ba32012-01-17 21:48:47 +02001202static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001203{
1204 struct discovery_state *discov = &hdev->discovery;
1205 struct inquiry_entry *e;
1206
Johan Hedbergb644ba32012-01-17 21:48:47 +02001207 if (list_empty(&discov->resolve))
1208 return false;
1209
1210 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001211 if (!e)
1212 return false;
1213
Johan Hedbergb644ba32012-01-17 21:48:47 +02001214 if (hci_resolve_name(hdev, e) == 0) {
1215 e->name_state = NAME_PENDING;
1216 return true;
1217 }
1218
1219 return false;
1220}
1221
1222static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001223 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001224{
1225 struct discovery_state *discov = &hdev->discovery;
1226 struct inquiry_entry *e;
1227
1228 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001229 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1230 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001231
1232 if (discov->state == DISCOVERY_STOPPED)
1233 return;
1234
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001235 if (discov->state == DISCOVERY_STOPPING)
1236 goto discov_complete;
1237
1238 if (discov->state != DISCOVERY_RESOLVING)
1239 return;
1240
1241 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001242 /* If the device was not found in a list of found devices names of which
1243 * are pending. there is no need to continue resolving a next name as it
1244 * will be done upon receiving another Remote Name Request Complete
1245 * Event */
1246 if (!e)
1247 return;
1248
1249 list_del(&e->list);
1250 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001251 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001252 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1253 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001254 } else {
1255 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001256 }
1257
Johan Hedbergb644ba32012-01-17 21:48:47 +02001258 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001259 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001260
1261discov_complete:
1262 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1263}
1264
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001265static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1266{
Johan Hedberg127178d2010-11-18 22:22:29 +02001267 struct hci_cp_remote_name_req *cp;
1268 struct hci_conn *conn;
1269
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001270 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001271
1272 /* If successful wait for the name req complete event before
1273 * checking for the need to do authentication */
1274 if (!status)
1275 return;
1276
1277 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1278 if (!cp)
1279 return;
1280
1281 hci_dev_lock(hdev);
1282
1283 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001284
1285 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1286 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1287
Johan Hedberg79c6c702011-04-28 11:28:55 -07001288 if (!conn)
1289 goto unlock;
1290
1291 if (!hci_outgoing_auth_needed(hdev, conn))
1292 goto unlock;
1293
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001294 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001295 struct hci_cp_auth_requested cp;
1296 cp.handle = __cpu_to_le16(conn->handle);
1297 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1298 }
1299
Johan Hedberg79c6c702011-04-28 11:28:55 -07001300unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001301 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001302}
1303
Marcel Holtmann769be972008-07-14 20:13:49 +02001304static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1305{
1306 struct hci_cp_read_remote_features *cp;
1307 struct hci_conn *conn;
1308
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001309 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001310
1311 if (!status)
1312 return;
1313
1314 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1315 if (!cp)
1316 return;
1317
1318 hci_dev_lock(hdev);
1319
1320 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1321 if (conn) {
1322 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001323 hci_proto_connect_cfm(conn, status);
1324 hci_conn_put(conn);
1325 }
1326 }
1327
1328 hci_dev_unlock(hdev);
1329}
1330
1331static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1332{
1333 struct hci_cp_read_remote_ext_features *cp;
1334 struct hci_conn *conn;
1335
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001336 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001337
1338 if (!status)
1339 return;
1340
1341 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1342 if (!cp)
1343 return;
1344
1345 hci_dev_lock(hdev);
1346
1347 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1348 if (conn) {
1349 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001350 hci_proto_connect_cfm(conn, status);
1351 hci_conn_put(conn);
1352 }
1353 }
1354
1355 hci_dev_unlock(hdev);
1356}
1357
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001358static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1359{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001360 struct hci_cp_setup_sync_conn *cp;
1361 struct hci_conn *acl, *sco;
1362 __u16 handle;
1363
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001364 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001365
1366 if (!status)
1367 return;
1368
1369 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1370 if (!cp)
1371 return;
1372
1373 handle = __le16_to_cpu(cp->handle);
1374
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001375 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001376
1377 hci_dev_lock(hdev);
1378
1379 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001380 if (acl) {
1381 sco = acl->link;
1382 if (sco) {
1383 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001384
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001385 hci_proto_connect_cfm(sco, status);
1386 hci_conn_del(sco);
1387 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001388 }
1389
1390 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001391}
1392
1393static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1394{
1395 struct hci_cp_sniff_mode *cp;
1396 struct hci_conn *conn;
1397
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001398 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001399
1400 if (!status)
1401 return;
1402
1403 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1404 if (!cp)
1405 return;
1406
1407 hci_dev_lock(hdev);
1408
1409 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001410 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001411 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001412
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001413 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001414 hci_sco_setup(conn, status);
1415 }
1416
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001417 hci_dev_unlock(hdev);
1418}
1419
1420static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1421{
1422 struct hci_cp_exit_sniff_mode *cp;
1423 struct hci_conn *conn;
1424
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001425 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001426
1427 if (!status)
1428 return;
1429
1430 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1431 if (!cp)
1432 return;
1433
1434 hci_dev_lock(hdev);
1435
1436 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001437 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001438 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001439
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001440 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001441 hci_sco_setup(conn, status);
1442 }
1443
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001444 hci_dev_unlock(hdev);
1445}
1446
Johan Hedberg88c3df12012-02-09 14:27:38 +02001447static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1448{
1449 struct hci_cp_disconnect *cp;
1450 struct hci_conn *conn;
1451
1452 if (!status)
1453 return;
1454
1455 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1456 if (!cp)
1457 return;
1458
1459 hci_dev_lock(hdev);
1460
1461 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1462 if (conn)
1463 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001464 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001465
1466 hci_dev_unlock(hdev);
1467}
1468
Ville Tervofcd89c02011-02-10 22:38:47 -03001469static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1470{
Ville Tervofcd89c02011-02-10 22:38:47 -03001471 struct hci_conn *conn;
1472
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001473 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Ville Tervofcd89c02011-02-10 22:38:47 -03001474
Ville Tervofcd89c02011-02-10 22:38:47 -03001475 if (status) {
Andre Guedesf00a06a2012-07-27 15:10:13 -03001476 hci_dev_lock(hdev);
Ville Tervofcd89c02011-02-10 22:38:47 -03001477
Andre Guedes0c95ab72012-07-27 15:10:14 -03001478 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001479 if (!conn) {
1480 hci_dev_unlock(hdev);
1481 return;
1482 }
1483
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001484 BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001485
1486 conn->state = BT_CLOSED;
Andre Guedes0c95ab72012-07-27 15:10:14 -03001487 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Andre Guedesf00a06a2012-07-27 15:10:13 -03001488 conn->dst_type, status);
1489 hci_proto_connect_cfm(conn, status);
1490 hci_conn_del(conn);
1491
1492 hci_dev_unlock(hdev);
1493 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001494}
1495
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001496static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1497{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001498 struct hci_cp_create_phy_link *cp;
1499
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001500 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001501
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001502 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1503 if (!cp)
1504 return;
1505
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001506 hci_dev_lock(hdev);
1507
1508 if (status) {
1509 struct hci_conn *hcon;
1510
1511 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1512 if (hcon)
1513 hci_conn_del(hcon);
1514 } else {
1515 amp_write_remote_assoc(hdev, cp->phy_handle);
1516 }
1517
1518 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001519}
1520
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001521static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1522{
1523 struct hci_cp_accept_phy_link *cp;
1524
1525 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1526
1527 if (status)
1528 return;
1529
1530 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1531 if (!cp)
1532 return;
1533
1534 amp_write_remote_assoc(hdev, cp->phy_handle);
1535}
1536
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001537static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001538{
1539 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001540 struct discovery_state *discov = &hdev->discovery;
1541 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001542
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001543 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001544
Johan Hedberg9238f362013-03-05 20:37:48 +02001545 hci_req_cmd_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001546
1547 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001548
1549 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1550 return;
1551
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001552 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001553 return;
1554
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001555 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001556
Andre Guedes343f9352012-02-17 20:39:37 -03001557 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001558 goto unlock;
1559
1560 if (list_empty(&discov->resolve)) {
1561 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1562 goto unlock;
1563 }
1564
1565 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1566 if (e && hci_resolve_name(hdev, e) == 0) {
1567 e->name_state = NAME_PENDING;
1568 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1569 } else {
1570 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1571 }
1572
1573unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001574 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001575}
1576
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001577static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001579 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001580 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 int num_rsp = *((__u8 *) skb->data);
1582
1583 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1584
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001585 if (!num_rsp)
1586 return;
1587
Andre Guedes1519cc12012-03-21 00:03:38 -03001588 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1589 return;
1590
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001592
Johan Hedberge17acd42011-03-30 23:57:16 +03001593 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001594 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001595
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 bacpy(&data.bdaddr, &info->bdaddr);
1597 data.pscan_rep_mode = info->pscan_rep_mode;
1598 data.pscan_period_mode = info->pscan_period_mode;
1599 data.pscan_mode = info->pscan_mode;
1600 memcpy(data.dev_class, info->dev_class, 3);
1601 data.clock_offset = info->clock_offset;
1602 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001603 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001604
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001605 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001606 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001607 info->dev_class, 0, !name_known, ssp, NULL,
1608 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001610
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 hci_dev_unlock(hdev);
1612}
1613
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001614static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001616 struct hci_ev_conn_complete *ev = (void *) skb->data;
1617 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001619 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001620
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001622
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001623 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001624 if (!conn) {
1625 if (ev->link_type != SCO_LINK)
1626 goto unlock;
1627
1628 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1629 if (!conn)
1630 goto unlock;
1631
1632 conn->type = SCO_LINK;
1633 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001634
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001635 if (!ev->status) {
1636 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001637
1638 if (conn->type == ACL_LINK) {
1639 conn->state = BT_CONFIG;
1640 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001641
1642 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1643 !hci_find_link_key(hdev, &ev->bdaddr))
1644 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1645 else
1646 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001647 } else
1648 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001649
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001650 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001651 hci_conn_add_sysfs(conn);
1652
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001653 if (test_bit(HCI_AUTH, &hdev->flags))
1654 conn->link_mode |= HCI_LM_AUTH;
1655
1656 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1657 conn->link_mode |= HCI_LM_ENCRYPT;
1658
1659 /* Get remote features */
1660 if (conn->type == ACL_LINK) {
1661 struct hci_cp_read_remote_features cp;
1662 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001663 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001664 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001665 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001666
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001667 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001668 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001669 struct hci_cp_change_conn_ptype cp;
1670 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001671 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001672 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1673 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001674 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001675 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001676 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001677 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001678 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001679 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001680 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001681
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001682 if (conn->type == ACL_LINK)
1683 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001684
Marcel Holtmann769be972008-07-14 20:13:49 +02001685 if (ev->status) {
1686 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001687 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001688 } else if (ev->link_type != ACL_LINK)
1689 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001690
1691unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001693
1694 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695}
1696
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001697void hci_conn_accept(struct hci_conn *conn, int mask)
1698{
1699 struct hci_dev *hdev = conn->hdev;
1700
1701 BT_DBG("conn %p", conn);
1702
1703 conn->state = BT_CONFIG;
1704
1705 if (!lmp_esco_capable(hdev)) {
1706 struct hci_cp_accept_conn_req cp;
1707
1708 bacpy(&cp.bdaddr, &conn->dst);
1709
1710 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1711 cp.role = 0x00; /* Become master */
1712 else
1713 cp.role = 0x01; /* Remain slave */
1714
1715 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
1716 } else /* lmp_esco_capable(hdev)) */ {
1717 struct hci_cp_accept_sync_conn_req cp;
1718
1719 bacpy(&cp.bdaddr, &conn->dst);
1720 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1721
1722 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1723 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1724 cp.max_latency = __constant_cpu_to_le16(0xffff);
1725 cp.content_format = cpu_to_le16(hdev->voice_setting);
1726 cp.retrans_effort = 0xff;
1727
1728 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1729 sizeof(cp), &cp);
1730 }
1731}
1732
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001733static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001735 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001737 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001739 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001740 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001742 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1743 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744
Szymon Janc138d22e2011-02-17 16:44:23 +01001745 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001746 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001748 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750
1751 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001752
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001753 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1754 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001755 memcpy(ie->data.dev_class, ev->dev_class, 3);
1756
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001757 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1758 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001760 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1761 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001762 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 hci_dev_unlock(hdev);
1764 return;
1765 }
1766 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001767
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001769
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 hci_dev_unlock(hdev);
1771
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001772 if (ev->link_type == ACL_LINK ||
1773 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001774 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001775 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001777 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001779 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1780 cp.role = 0x00; /* Become master */
1781 else
1782 cp.role = 0x01; /* Remain slave */
1783
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001784 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1785 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001786 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001787 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001788 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001789
1790 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001791 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001792
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001793 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1794 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1795 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001796 cp.content_format = cpu_to_le16(hdev->voice_setting);
1797 cp.retrans_effort = 0xff;
1798
1799 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001800 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001801 } else {
1802 conn->state = BT_CONNECT2;
1803 hci_proto_connect_cfm(conn, 0);
1804 hci_conn_put(conn);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001805 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 } else {
1807 /* Connection rejected */
1808 struct hci_cp_reject_conn_req cp;
1809
1810 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001811 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001812 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 }
1814}
1815
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001816static u8 hci_to_mgmt_reason(u8 err)
1817{
1818 switch (err) {
1819 case HCI_ERROR_CONNECTION_TIMEOUT:
1820 return MGMT_DEV_DISCONN_TIMEOUT;
1821 case HCI_ERROR_REMOTE_USER_TERM:
1822 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1823 case HCI_ERROR_REMOTE_POWER_OFF:
1824 return MGMT_DEV_DISCONN_REMOTE;
1825 case HCI_ERROR_LOCAL_HOST_TERM:
1826 return MGMT_DEV_DISCONN_LOCAL_HOST;
1827 default:
1828 return MGMT_DEV_DISCONN_UNKNOWN;
1829 }
1830}
1831
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001832static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001834 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001835 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001837 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839 hci_dev_lock(hdev);
1840
Marcel Holtmann04837f62006-07-03 10:02:33 +02001841 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001842 if (!conn)
1843 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001844
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001845 if (ev->status == 0)
1846 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847
Johan Hedbergb644ba32012-01-17 21:48:47 +02001848 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001849 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001850 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001851 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001852 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001853 } else {
1854 u8 reason = hci_to_mgmt_reason(ev->reason);
1855
Johan Hedbergafc747a2012-01-15 18:11:07 +02001856 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001857 conn->dst_type, reason);
1858 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001859 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001860
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001861 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301862 if (conn->type == ACL_LINK && conn->flush_key)
1863 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001864 hci_proto_disconn_cfm(conn, ev->reason);
1865 hci_conn_del(conn);
1866 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001867
1868unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869 hci_dev_unlock(hdev);
1870}
1871
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001872static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001873{
1874 struct hci_ev_auth_complete *ev = (void *) skb->data;
1875 struct hci_conn *conn;
1876
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001877 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001878
1879 hci_dev_lock(hdev);
1880
1881 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001882 if (!conn)
1883 goto unlock;
1884
1885 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001886 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001887 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001888 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001889 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001890 conn->link_mode |= HCI_LM_AUTH;
1891 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001892 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001893 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001894 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001895 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001896 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001897
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001898 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1899 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001900
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001901 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001902 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001903 struct hci_cp_set_conn_encrypt cp;
1904 cp.handle = ev->handle;
1905 cp.encrypt = 0x01;
1906 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001907 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001908 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001909 conn->state = BT_CONNECTED;
1910 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001911 hci_conn_put(conn);
1912 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001913 } else {
1914 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001915
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001916 hci_conn_hold(conn);
1917 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1918 hci_conn_put(conn);
1919 }
1920
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001921 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001922 if (!ev->status) {
1923 struct hci_cp_set_conn_encrypt cp;
1924 cp.handle = ev->handle;
1925 cp.encrypt = 0x01;
1926 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001927 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001928 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001929 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001930 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001931 }
1932 }
1933
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001934unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001935 hci_dev_unlock(hdev);
1936}
1937
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001938static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001939{
Johan Hedberg127178d2010-11-18 22:22:29 +02001940 struct hci_ev_remote_name *ev = (void *) skb->data;
1941 struct hci_conn *conn;
1942
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001943 BT_DBG("%s", hdev->name);
1944
1945 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001946
1947 hci_dev_lock(hdev);
1948
1949 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001950
1951 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1952 goto check_auth;
1953
1954 if (ev->status == 0)
1955 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001956 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001957 else
1958 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1959
1960check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001961 if (!conn)
1962 goto unlock;
1963
1964 if (!hci_outgoing_auth_needed(hdev, conn))
1965 goto unlock;
1966
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001967 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001968 struct hci_cp_auth_requested cp;
1969 cp.handle = __cpu_to_le16(conn->handle);
1970 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1971 }
1972
Johan Hedberg79c6c702011-04-28 11:28:55 -07001973unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001974 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001975}
1976
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001977static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001978{
1979 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1980 struct hci_conn *conn;
1981
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001982 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001983
1984 hci_dev_lock(hdev);
1985
1986 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1987 if (conn) {
1988 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001989 if (ev->encrypt) {
1990 /* Encryption implies authentication */
1991 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001992 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001993 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001994 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001995 conn->link_mode &= ~HCI_LM_ENCRYPT;
1996 }
1997
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001998 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001999
Gustavo Padovana7d77232012-05-13 03:20:07 -03002000 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03002001 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
Gustavo Padovana7d77232012-05-13 03:20:07 -03002002 hci_conn_put(conn);
2003 goto unlock;
2004 }
2005
Marcel Holtmannf8558552008-07-14 20:13:49 +02002006 if (conn->state == BT_CONFIG) {
2007 if (!ev->status)
2008 conn->state = BT_CONNECTED;
2009
2010 hci_proto_connect_cfm(conn, ev->status);
2011 hci_conn_put(conn);
2012 } else
2013 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002014 }
2015
Gustavo Padovana7d77232012-05-13 03:20:07 -03002016unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002017 hci_dev_unlock(hdev);
2018}
2019
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002020static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2021 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002022{
2023 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2024 struct hci_conn *conn;
2025
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002026 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002027
2028 hci_dev_lock(hdev);
2029
2030 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2031 if (conn) {
2032 if (!ev->status)
2033 conn->link_mode |= HCI_LM_SECURE;
2034
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002035 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002036
2037 hci_key_change_cfm(conn, ev->status);
2038 }
2039
2040 hci_dev_unlock(hdev);
2041}
2042
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002043static void hci_remote_features_evt(struct hci_dev *hdev,
2044 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002045{
2046 struct hci_ev_remote_features *ev = (void *) skb->data;
2047 struct hci_conn *conn;
2048
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002049 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002050
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002051 hci_dev_lock(hdev);
2052
2053 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002054 if (!conn)
2055 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002056
Johan Hedbergccd556f2010-11-10 17:11:51 +02002057 if (!ev->status)
2058 memcpy(conn->features, ev->features, 8);
2059
2060 if (conn->state != BT_CONFIG)
2061 goto unlock;
2062
2063 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2064 struct hci_cp_read_remote_ext_features cp;
2065 cp.handle = ev->handle;
2066 cp.page = 0x01;
2067 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002068 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002069 goto unlock;
2070 }
2071
Johan Hedberg671267b2012-05-12 16:11:50 -03002072 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002073 struct hci_cp_remote_name_req cp;
2074 memset(&cp, 0, sizeof(cp));
2075 bacpy(&cp.bdaddr, &conn->dst);
2076 cp.pscan_rep_mode = 0x02;
2077 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002078 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2079 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002080 conn->dst_type, 0, NULL, 0,
2081 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002082
Johan Hedberg127178d2010-11-18 22:22:29 +02002083 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002084 conn->state = BT_CONNECTED;
2085 hci_proto_connect_cfm(conn, ev->status);
2086 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002087 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002088
Johan Hedbergccd556f2010-11-10 17:11:51 +02002089unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002090 hci_dev_unlock(hdev);
2091}
2092
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002093static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002094{
2095 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002096 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002097 __u16 opcode;
2098
2099 skb_pull(skb, sizeof(*ev));
2100
2101 opcode = __le16_to_cpu(ev->opcode);
2102
2103 switch (opcode) {
2104 case HCI_OP_INQUIRY_CANCEL:
2105 hci_cc_inquiry_cancel(hdev, skb);
2106 break;
2107
Andre Guedes4d934832012-03-21 00:03:35 -03002108 case HCI_OP_PERIODIC_INQ:
2109 hci_cc_periodic_inq(hdev, skb);
2110 break;
2111
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002112 case HCI_OP_EXIT_PERIODIC_INQ:
2113 hci_cc_exit_periodic_inq(hdev, skb);
2114 break;
2115
2116 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2117 hci_cc_remote_name_req_cancel(hdev, skb);
2118 break;
2119
2120 case HCI_OP_ROLE_DISCOVERY:
2121 hci_cc_role_discovery(hdev, skb);
2122 break;
2123
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002124 case HCI_OP_READ_LINK_POLICY:
2125 hci_cc_read_link_policy(hdev, skb);
2126 break;
2127
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002128 case HCI_OP_WRITE_LINK_POLICY:
2129 hci_cc_write_link_policy(hdev, skb);
2130 break;
2131
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002132 case HCI_OP_READ_DEF_LINK_POLICY:
2133 hci_cc_read_def_link_policy(hdev, skb);
2134 break;
2135
2136 case HCI_OP_WRITE_DEF_LINK_POLICY:
2137 hci_cc_write_def_link_policy(hdev, skb);
2138 break;
2139
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002140 case HCI_OP_RESET:
2141 hci_cc_reset(hdev, skb);
2142 break;
2143
2144 case HCI_OP_WRITE_LOCAL_NAME:
2145 hci_cc_write_local_name(hdev, skb);
2146 break;
2147
2148 case HCI_OP_READ_LOCAL_NAME:
2149 hci_cc_read_local_name(hdev, skb);
2150 break;
2151
2152 case HCI_OP_WRITE_AUTH_ENABLE:
2153 hci_cc_write_auth_enable(hdev, skb);
2154 break;
2155
2156 case HCI_OP_WRITE_ENCRYPT_MODE:
2157 hci_cc_write_encrypt_mode(hdev, skb);
2158 break;
2159
2160 case HCI_OP_WRITE_SCAN_ENABLE:
2161 hci_cc_write_scan_enable(hdev, skb);
2162 break;
2163
2164 case HCI_OP_READ_CLASS_OF_DEV:
2165 hci_cc_read_class_of_dev(hdev, skb);
2166 break;
2167
2168 case HCI_OP_WRITE_CLASS_OF_DEV:
2169 hci_cc_write_class_of_dev(hdev, skb);
2170 break;
2171
2172 case HCI_OP_READ_VOICE_SETTING:
2173 hci_cc_read_voice_setting(hdev, skb);
2174 break;
2175
2176 case HCI_OP_WRITE_VOICE_SETTING:
2177 hci_cc_write_voice_setting(hdev, skb);
2178 break;
2179
Marcel Holtmann333140b2008-07-14 20:13:48 +02002180 case HCI_OP_WRITE_SSP_MODE:
2181 hci_cc_write_ssp_mode(hdev, skb);
2182 break;
2183
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002184 case HCI_OP_READ_LOCAL_VERSION:
2185 hci_cc_read_local_version(hdev, skb);
2186 break;
2187
2188 case HCI_OP_READ_LOCAL_COMMANDS:
2189 hci_cc_read_local_commands(hdev, skb);
2190 break;
2191
2192 case HCI_OP_READ_LOCAL_FEATURES:
2193 hci_cc_read_local_features(hdev, skb);
2194 break;
2195
Andre Guedes971e3a42011-06-30 19:20:52 -03002196 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2197 hci_cc_read_local_ext_features(hdev, skb);
2198 break;
2199
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002200 case HCI_OP_READ_BUFFER_SIZE:
2201 hci_cc_read_buffer_size(hdev, skb);
2202 break;
2203
2204 case HCI_OP_READ_BD_ADDR:
2205 hci_cc_read_bd_addr(hdev, skb);
2206 break;
2207
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002208 case HCI_OP_READ_DATA_BLOCK_SIZE:
2209 hci_cc_read_data_block_size(hdev, skb);
2210 break;
2211
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002212 case HCI_OP_READ_FLOW_CONTROL_MODE:
2213 hci_cc_read_flow_control_mode(hdev, skb);
2214 break;
2215
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002216 case HCI_OP_READ_LOCAL_AMP_INFO:
2217 hci_cc_read_local_amp_info(hdev, skb);
2218 break;
2219
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002220 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2221 hci_cc_read_local_amp_assoc(hdev, skb);
2222 break;
2223
Johan Hedbergd5859e22011-01-25 01:19:58 +02002224 case HCI_OP_READ_INQ_RSP_TX_POWER:
2225 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2226 break;
2227
Johan Hedberg980e1a52011-01-22 06:10:07 +02002228 case HCI_OP_PIN_CODE_REPLY:
2229 hci_cc_pin_code_reply(hdev, skb);
2230 break;
2231
2232 case HCI_OP_PIN_CODE_NEG_REPLY:
2233 hci_cc_pin_code_neg_reply(hdev, skb);
2234 break;
2235
Szymon Jancc35938b2011-03-22 13:12:21 +01002236 case HCI_OP_READ_LOCAL_OOB_DATA:
2237 hci_cc_read_local_oob_data_reply(hdev, skb);
2238 break;
2239
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002240 case HCI_OP_LE_READ_BUFFER_SIZE:
2241 hci_cc_le_read_buffer_size(hdev, skb);
2242 break;
2243
Johan Hedberg60e77322013-01-22 14:01:59 +02002244 case HCI_OP_LE_READ_LOCAL_FEATURES:
2245 hci_cc_le_read_local_features(hdev, skb);
2246 break;
2247
Johan Hedberg8fa19092012-10-19 20:57:49 +03002248 case HCI_OP_LE_READ_ADV_TX_POWER:
2249 hci_cc_le_read_adv_tx_power(hdev, skb);
2250 break;
2251
Johan Hedberga5c29682011-02-19 12:05:57 -03002252 case HCI_OP_USER_CONFIRM_REPLY:
2253 hci_cc_user_confirm_reply(hdev, skb);
2254 break;
2255
2256 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2257 hci_cc_user_confirm_neg_reply(hdev, skb);
2258 break;
2259
Brian Gix1143d452011-11-23 08:28:34 -08002260 case HCI_OP_USER_PASSKEY_REPLY:
2261 hci_cc_user_passkey_reply(hdev, skb);
2262 break;
2263
2264 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2265 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002266 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002267
2268 case HCI_OP_LE_SET_SCAN_PARAM:
2269 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002270 break;
2271
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002272 case HCI_OP_LE_SET_ADV_ENABLE:
2273 hci_cc_le_set_adv_enable(hdev, skb);
2274 break;
2275
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002276 case HCI_OP_LE_SET_SCAN_ENABLE:
2277 hci_cc_le_set_scan_enable(hdev, skb);
2278 break;
2279
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002280 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2281 hci_cc_le_read_white_list_size(hdev, skb);
2282 break;
2283
Johan Hedberg9b008c02013-01-22 14:02:01 +02002284 case HCI_OP_LE_READ_SUPPORTED_STATES:
2285 hci_cc_le_read_supported_states(hdev, skb);
2286 break;
2287
Andre Guedesf9b49302011-06-30 19:20:53 -03002288 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2289 hci_cc_write_le_host_supported(hdev, skb);
2290 break;
2291
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002292 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2293 hci_cc_write_remote_amp_assoc(hdev, skb);
2294 break;
2295
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002296 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002297 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002298 break;
2299 }
2300
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002301 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002302 del_timer(&hdev->cmd_timer);
2303
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002304 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002305
Szymon Jancdbccd792012-12-11 08:51:19 +01002306 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002307 atomic_set(&hdev->cmd_cnt, 1);
2308 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002309 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002310 }
2311}
2312
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002313static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002314{
2315 struct hci_ev_cmd_status *ev = (void *) skb->data;
2316 __u16 opcode;
2317
2318 skb_pull(skb, sizeof(*ev));
2319
2320 opcode = __le16_to_cpu(ev->opcode);
2321
2322 switch (opcode) {
2323 case HCI_OP_INQUIRY:
2324 hci_cs_inquiry(hdev, ev->status);
2325 break;
2326
2327 case HCI_OP_CREATE_CONN:
2328 hci_cs_create_conn(hdev, ev->status);
2329 break;
2330
2331 case HCI_OP_ADD_SCO:
2332 hci_cs_add_sco(hdev, ev->status);
2333 break;
2334
Marcel Holtmannf8558552008-07-14 20:13:49 +02002335 case HCI_OP_AUTH_REQUESTED:
2336 hci_cs_auth_requested(hdev, ev->status);
2337 break;
2338
2339 case HCI_OP_SET_CONN_ENCRYPT:
2340 hci_cs_set_conn_encrypt(hdev, ev->status);
2341 break;
2342
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002343 case HCI_OP_REMOTE_NAME_REQ:
2344 hci_cs_remote_name_req(hdev, ev->status);
2345 break;
2346
Marcel Holtmann769be972008-07-14 20:13:49 +02002347 case HCI_OP_READ_REMOTE_FEATURES:
2348 hci_cs_read_remote_features(hdev, ev->status);
2349 break;
2350
2351 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2352 hci_cs_read_remote_ext_features(hdev, ev->status);
2353 break;
2354
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002355 case HCI_OP_SETUP_SYNC_CONN:
2356 hci_cs_setup_sync_conn(hdev, ev->status);
2357 break;
2358
2359 case HCI_OP_SNIFF_MODE:
2360 hci_cs_sniff_mode(hdev, ev->status);
2361 break;
2362
2363 case HCI_OP_EXIT_SNIFF_MODE:
2364 hci_cs_exit_sniff_mode(hdev, ev->status);
2365 break;
2366
Johan Hedberg8962ee72011-01-20 12:40:27 +02002367 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002368 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002369 break;
2370
Ville Tervofcd89c02011-02-10 22:38:47 -03002371 case HCI_OP_LE_CREATE_CONN:
2372 hci_cs_le_create_conn(hdev, ev->status);
2373 break;
2374
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002375 case HCI_OP_CREATE_PHY_LINK:
2376 hci_cs_create_phylink(hdev, ev->status);
2377 break;
2378
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002379 case HCI_OP_ACCEPT_PHY_LINK:
2380 hci_cs_accept_phylink(hdev, ev->status);
2381 break;
2382
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002383 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002384 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002385 break;
2386 }
2387
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002388 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002389 del_timer(&hdev->cmd_timer);
2390
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002391 hci_req_cmd_status(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002392
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002393 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002394 atomic_set(&hdev->cmd_cnt, 1);
2395 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002396 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002397 }
2398}
2399
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002400static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002401{
2402 struct hci_ev_role_change *ev = (void *) skb->data;
2403 struct hci_conn *conn;
2404
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002405 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002406
2407 hci_dev_lock(hdev);
2408
2409 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2410 if (conn) {
2411 if (!ev->status) {
2412 if (ev->role)
2413 conn->link_mode &= ~HCI_LM_MASTER;
2414 else
2415 conn->link_mode |= HCI_LM_MASTER;
2416 }
2417
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002418 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002419
2420 hci_role_switch_cfm(conn, ev->status, ev->role);
2421 }
2422
2423 hci_dev_unlock(hdev);
2424}
2425
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002426static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002428 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002429 int i;
2430
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002431 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2432 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2433 return;
2434 }
2435
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002436 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002437 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438 BT_DBG("%s bad parameters", hdev->name);
2439 return;
2440 }
2441
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002442 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2443
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002444 for (i = 0; i < ev->num_hndl; i++) {
2445 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446 struct hci_conn *conn;
2447 __u16 handle, count;
2448
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002449 handle = __le16_to_cpu(info->handle);
2450 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451
2452 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002453 if (!conn)
2454 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002456 conn->sent -= count;
2457
2458 switch (conn->type) {
2459 case ACL_LINK:
2460 hdev->acl_cnt += count;
2461 if (hdev->acl_cnt > hdev->acl_pkts)
2462 hdev->acl_cnt = hdev->acl_pkts;
2463 break;
2464
2465 case LE_LINK:
2466 if (hdev->le_pkts) {
2467 hdev->le_cnt += count;
2468 if (hdev->le_cnt > hdev->le_pkts)
2469 hdev->le_cnt = hdev->le_pkts;
2470 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002471 hdev->acl_cnt += count;
2472 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473 hdev->acl_cnt = hdev->acl_pkts;
2474 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002475 break;
2476
2477 case SCO_LINK:
2478 hdev->sco_cnt += count;
2479 if (hdev->sco_cnt > hdev->sco_pkts)
2480 hdev->sco_cnt = hdev->sco_pkts;
2481 break;
2482
2483 default:
2484 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2485 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486 }
2487 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002488
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002489 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002490}
2491
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002492static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2493 __u16 handle)
2494{
2495 struct hci_chan *chan;
2496
2497 switch (hdev->dev_type) {
2498 case HCI_BREDR:
2499 return hci_conn_hash_lookup_handle(hdev, handle);
2500 case HCI_AMP:
2501 chan = hci_chan_lookup_handle(hdev, handle);
2502 if (chan)
2503 return chan->conn;
2504 break;
2505 default:
2506 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2507 break;
2508 }
2509
2510 return NULL;
2511}
2512
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002513static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002514{
2515 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2516 int i;
2517
2518 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2519 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2520 return;
2521 }
2522
2523 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002524 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002525 BT_DBG("%s bad parameters", hdev->name);
2526 return;
2527 }
2528
2529 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002530 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002531
2532 for (i = 0; i < ev->num_hndl; i++) {
2533 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002534 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002535 __u16 handle, block_count;
2536
2537 handle = __le16_to_cpu(info->handle);
2538 block_count = __le16_to_cpu(info->blocks);
2539
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002540 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002541 if (!conn)
2542 continue;
2543
2544 conn->sent -= block_count;
2545
2546 switch (conn->type) {
2547 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002548 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002549 hdev->block_cnt += block_count;
2550 if (hdev->block_cnt > hdev->num_blocks)
2551 hdev->block_cnt = hdev->num_blocks;
2552 break;
2553
2554 default:
2555 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2556 break;
2557 }
2558 }
2559
2560 queue_work(hdev->workqueue, &hdev->tx_work);
2561}
2562
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002563static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002565 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002566 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002568 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569
2570 hci_dev_lock(hdev);
2571
Marcel Holtmann04837f62006-07-03 10:02:33 +02002572 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2573 if (conn) {
2574 conn->mode = ev->mode;
2575 conn->interval = __le16_to_cpu(ev->interval);
2576
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002577 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2578 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002579 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002580 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002581 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002582 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002583 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002584
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002585 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002586 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002587 }
2588
2589 hci_dev_unlock(hdev);
2590}
2591
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002592static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002593{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002594 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2595 struct hci_conn *conn;
2596
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002597 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002598
2599 hci_dev_lock(hdev);
2600
2601 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002602 if (!conn)
2603 goto unlock;
2604
2605 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002606 hci_conn_hold(conn);
2607 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2608 hci_conn_put(conn);
2609 }
2610
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002611 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002612 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002613 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002614 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002615 u8 secure;
2616
2617 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2618 secure = 1;
2619 else
2620 secure = 0;
2621
Johan Hedberg744cf192011-11-08 20:40:14 +02002622 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002623 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002624
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002625unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002626 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627}
2628
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002629static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002631 struct hci_ev_link_key_req *ev = (void *) skb->data;
2632 struct hci_cp_link_key_reply cp;
2633 struct hci_conn *conn;
2634 struct link_key *key;
2635
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002636 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002637
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002638 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002639 return;
2640
2641 hci_dev_lock(hdev);
2642
2643 key = hci_find_link_key(hdev, &ev->bdaddr);
2644 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002645 BT_DBG("%s link key not found for %pMR", hdev->name,
2646 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002647 goto not_found;
2648 }
2649
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002650 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2651 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002652
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002653 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002654 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002655 BT_DBG("%s ignoring debug key", hdev->name);
2656 goto not_found;
2657 }
2658
2659 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002660 if (conn) {
2661 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002662 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002663 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2664 goto not_found;
2665 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002666
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002667 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002668 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002669 BT_DBG("%s ignoring key unauthenticated for high security",
2670 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002671 goto not_found;
2672 }
2673
2674 conn->key_type = key->type;
2675 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002676 }
2677
2678 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002679 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002680
2681 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2682
2683 hci_dev_unlock(hdev);
2684
2685 return;
2686
2687not_found:
2688 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2689 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002690}
2691
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002692static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002693{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002694 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2695 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002696 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002697
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002698 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002699
2700 hci_dev_lock(hdev);
2701
2702 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2703 if (conn) {
2704 hci_conn_hold(conn);
2705 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002706 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002707
2708 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2709 conn->key_type = ev->key_type;
2710
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002711 hci_conn_put(conn);
2712 }
2713
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002714 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002715 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002716 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002717
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002718 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719}
2720
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002721static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002722{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002723 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002724 struct hci_conn *conn;
2725
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002726 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002727
2728 hci_dev_lock(hdev);
2729
2730 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731 if (conn && !ev->status) {
2732 struct inquiry_entry *ie;
2733
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002734 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2735 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002736 ie->data.clock_offset = ev->clock_offset;
2737 ie->timestamp = jiffies;
2738 }
2739 }
2740
2741 hci_dev_unlock(hdev);
2742}
2743
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002744static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002745{
2746 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2747 struct hci_conn *conn;
2748
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002749 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002750
2751 hci_dev_lock(hdev);
2752
2753 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2754 if (conn && !ev->status)
2755 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2756
2757 hci_dev_unlock(hdev);
2758}
2759
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002760static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002761{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002762 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002763 struct inquiry_entry *ie;
2764
2765 BT_DBG("%s", hdev->name);
2766
2767 hci_dev_lock(hdev);
2768
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002769 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2770 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002771 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2772 ie->timestamp = jiffies;
2773 }
2774
2775 hci_dev_unlock(hdev);
2776}
2777
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002778static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2779 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002780{
2781 struct inquiry_data data;
2782 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002783 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002784
2785 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2786
2787 if (!num_rsp)
2788 return;
2789
Andre Guedes1519cc12012-03-21 00:03:38 -03002790 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2791 return;
2792
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002793 hci_dev_lock(hdev);
2794
2795 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002796 struct inquiry_info_with_rssi_and_pscan_mode *info;
2797 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002798
Johan Hedberge17acd42011-03-30 23:57:16 +03002799 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002800 bacpy(&data.bdaddr, &info->bdaddr);
2801 data.pscan_rep_mode = info->pscan_rep_mode;
2802 data.pscan_period_mode = info->pscan_period_mode;
2803 data.pscan_mode = info->pscan_mode;
2804 memcpy(data.dev_class, info->dev_class, 3);
2805 data.clock_offset = info->clock_offset;
2806 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002807 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002808
2809 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002810 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002811 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002812 info->dev_class, info->rssi,
2813 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002814 }
2815 } else {
2816 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2817
Johan Hedberge17acd42011-03-30 23:57:16 +03002818 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002819 bacpy(&data.bdaddr, &info->bdaddr);
2820 data.pscan_rep_mode = info->pscan_rep_mode;
2821 data.pscan_period_mode = info->pscan_period_mode;
2822 data.pscan_mode = 0x00;
2823 memcpy(data.dev_class, info->dev_class, 3);
2824 data.clock_offset = info->clock_offset;
2825 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002826 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002827 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002828 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002829 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002830 info->dev_class, info->rssi,
2831 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002832 }
2833 }
2834
2835 hci_dev_unlock(hdev);
2836}
2837
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002838static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2839 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002840{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002841 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2842 struct hci_conn *conn;
2843
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002844 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002845
Marcel Holtmann41a96212008-07-14 20:13:48 +02002846 hci_dev_lock(hdev);
2847
2848 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002849 if (!conn)
2850 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002851
Johan Hedbergccd556f2010-11-10 17:11:51 +02002852 if (!ev->status && ev->page == 0x01) {
2853 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002854
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002855 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2856 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002857 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002858
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002859 if (ev->features[0] & LMP_HOST_SSP)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002860 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002861 }
2862
Johan Hedbergccd556f2010-11-10 17:11:51 +02002863 if (conn->state != BT_CONFIG)
2864 goto unlock;
2865
Johan Hedberg671267b2012-05-12 16:11:50 -03002866 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002867 struct hci_cp_remote_name_req cp;
2868 memset(&cp, 0, sizeof(cp));
2869 bacpy(&cp.bdaddr, &conn->dst);
2870 cp.pscan_rep_mode = 0x02;
2871 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002872 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2873 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002874 conn->dst_type, 0, NULL, 0,
2875 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002876
Johan Hedberg127178d2010-11-18 22:22:29 +02002877 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002878 conn->state = BT_CONNECTED;
2879 hci_proto_connect_cfm(conn, ev->status);
2880 hci_conn_put(conn);
2881 }
2882
2883unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002884 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002885}
2886
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002887static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2888 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002889{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002890 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2891 struct hci_conn *conn;
2892
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002893 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002894
2895 hci_dev_lock(hdev);
2896
2897 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002898 if (!conn) {
2899 if (ev->link_type == ESCO_LINK)
2900 goto unlock;
2901
2902 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2903 if (!conn)
2904 goto unlock;
2905
2906 conn->type = SCO_LINK;
2907 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002908
Marcel Holtmann732547f2009-04-19 19:14:14 +02002909 switch (ev->status) {
2910 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002911 conn->handle = __le16_to_cpu(ev->handle);
2912 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002913
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002914 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002915 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002916 break;
2917
Stephen Coe705e5712010-02-16 11:29:44 -05002918 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002919 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002920 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002921 case 0x1f: /* Unspecified error */
2922 if (conn->out && conn->attempt < 2) {
2923 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2924 (hdev->esco_type & EDR_ESCO_MASK);
2925 hci_setup_sync(conn, conn->link->handle);
2926 goto unlock;
2927 }
2928 /* fall through */
2929
2930 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002931 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002932 break;
2933 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002934
2935 hci_proto_connect_cfm(conn, ev->status);
2936 if (ev->status)
2937 hci_conn_del(conn);
2938
2939unlock:
2940 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002941}
2942
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002943static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2944 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002945{
2946 struct inquiry_data data;
2947 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2948 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302949 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002950
2951 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2952
2953 if (!num_rsp)
2954 return;
2955
Andre Guedes1519cc12012-03-21 00:03:38 -03002956 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2957 return;
2958
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002959 hci_dev_lock(hdev);
2960
Johan Hedberge17acd42011-03-30 23:57:16 +03002961 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002962 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002963
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002964 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002965 data.pscan_rep_mode = info->pscan_rep_mode;
2966 data.pscan_period_mode = info->pscan_period_mode;
2967 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002968 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002969 data.clock_offset = info->clock_offset;
2970 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002971 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002972
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002973 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002974 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002975 sizeof(info->data),
2976 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002977 else
2978 name_known = true;
2979
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002980 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002981 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302982 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02002983 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002984 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302985 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002986 }
2987
2988 hci_dev_unlock(hdev);
2989}
2990
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002991static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
2992 struct sk_buff *skb)
2993{
2994 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
2995 struct hci_conn *conn;
2996
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002997 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002998 __le16_to_cpu(ev->handle));
2999
3000 hci_dev_lock(hdev);
3001
3002 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3003 if (!conn)
3004 goto unlock;
3005
3006 if (!ev->status)
3007 conn->sec_level = conn->pending_sec_level;
3008
3009 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3010
3011 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003012 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003013 hci_conn_put(conn);
3014 goto unlock;
3015 }
3016
3017 if (conn->state == BT_CONFIG) {
3018 if (!ev->status)
3019 conn->state = BT_CONNECTED;
3020
3021 hci_proto_connect_cfm(conn, ev->status);
3022 hci_conn_put(conn);
3023 } else {
3024 hci_auth_cfm(conn, ev->status);
3025
3026 hci_conn_hold(conn);
3027 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
3028 hci_conn_put(conn);
3029 }
3030
3031unlock:
3032 hci_dev_unlock(hdev);
3033}
3034
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003035static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003036{
3037 /* If remote requests dedicated bonding follow that lead */
3038 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3039 /* If both remote and local IO capabilities allow MITM
3040 * protection then require it, otherwise don't */
3041 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3042 return 0x02;
3043 else
3044 return 0x03;
3045 }
3046
3047 /* If remote requests no-bonding follow that lead */
3048 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003049 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003050
3051 return conn->auth_type;
3052}
3053
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003054static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003055{
3056 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3057 struct hci_conn *conn;
3058
3059 BT_DBG("%s", hdev->name);
3060
3061 hci_dev_lock(hdev);
3062
3063 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003064 if (!conn)
3065 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003066
Johan Hedberg03b555e2011-01-04 15:40:05 +02003067 hci_conn_hold(conn);
3068
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003069 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003070 goto unlock;
3071
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003072 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003073 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003074 struct hci_cp_io_capability_reply cp;
3075
3076 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303077 /* Change the IO capability from KeyboardDisplay
3078 * to DisplayYesNo as it is not supported by BT spec. */
3079 cp.capability = (conn->io_capability == 0x04) ?
3080 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003081 conn->auth_type = hci_get_auth_req(conn);
3082 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003083
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003084 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3085 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003086 cp.oob_data = 0x01;
3087 else
3088 cp.oob_data = 0x00;
3089
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003090 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003091 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003092 } else {
3093 struct hci_cp_io_capability_neg_reply cp;
3094
3095 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003096 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003097
3098 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003099 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003100 }
3101
3102unlock:
3103 hci_dev_unlock(hdev);
3104}
3105
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003106static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003107{
3108 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3109 struct hci_conn *conn;
3110
3111 BT_DBG("%s", hdev->name);
3112
3113 hci_dev_lock(hdev);
3114
3115 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3116 if (!conn)
3117 goto unlock;
3118
Johan Hedberg03b555e2011-01-04 15:40:05 +02003119 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003120 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003121 if (ev->oob_data)
3122 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003123
3124unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003125 hci_dev_unlock(hdev);
3126}
3127
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003128static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3129 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003130{
3131 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003132 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003133 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003134
3135 BT_DBG("%s", hdev->name);
3136
3137 hci_dev_lock(hdev);
3138
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003139 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003140 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003141
Johan Hedberg7a828902011-04-28 11:28:53 -07003142 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3143 if (!conn)
3144 goto unlock;
3145
3146 loc_mitm = (conn->auth_type & 0x01);
3147 rem_mitm = (conn->remote_auth & 0x01);
3148
3149 /* If we require MITM but the remote device can't provide that
3150 * (it has NoInputNoOutput) then reject the confirmation
3151 * request. The only exception is when we're dedicated bonding
3152 * initiators (connect_cfm_cb set) since then we always have the MITM
3153 * bit set. */
3154 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3155 BT_DBG("Rejecting request: remote device can't provide MITM");
3156 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003157 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003158 goto unlock;
3159 }
3160
3161 /* If no side requires MITM protection; auto-accept */
3162 if ((!loc_mitm || conn->remote_cap == 0x03) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003163 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003164
3165 /* If we're not the initiators request authorization to
3166 * proceed from user space (mgmt_user_confirm with
3167 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003168 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003169 BT_DBG("Confirming auto-accept as acceptor");
3170 confirm_hint = 1;
3171 goto confirm;
3172 }
3173
Johan Hedberg9f616562011-04-28 11:28:54 -07003174 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003175 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003176
3177 if (hdev->auto_accept_delay > 0) {
3178 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3179 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3180 goto unlock;
3181 }
3182
Johan Hedberg7a828902011-04-28 11:28:53 -07003183 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003184 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003185 goto unlock;
3186 }
3187
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003188confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003189 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003190 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003191
3192unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003193 hci_dev_unlock(hdev);
3194}
3195
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003196static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3197 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003198{
3199 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3200
3201 BT_DBG("%s", hdev->name);
3202
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003203 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003204 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003205}
3206
Johan Hedberg92a25252012-09-06 18:39:26 +03003207static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3208 struct sk_buff *skb)
3209{
3210 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3211 struct hci_conn *conn;
3212
3213 BT_DBG("%s", hdev->name);
3214
3215 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3216 if (!conn)
3217 return;
3218
3219 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3220 conn->passkey_entered = 0;
3221
3222 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3223 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3224 conn->dst_type, conn->passkey_notify,
3225 conn->passkey_entered);
3226}
3227
3228static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3229{
3230 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3231 struct hci_conn *conn;
3232
3233 BT_DBG("%s", hdev->name);
3234
3235 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3236 if (!conn)
3237 return;
3238
3239 switch (ev->type) {
3240 case HCI_KEYPRESS_STARTED:
3241 conn->passkey_entered = 0;
3242 return;
3243
3244 case HCI_KEYPRESS_ENTERED:
3245 conn->passkey_entered++;
3246 break;
3247
3248 case HCI_KEYPRESS_ERASED:
3249 conn->passkey_entered--;
3250 break;
3251
3252 case HCI_KEYPRESS_CLEARED:
3253 conn->passkey_entered = 0;
3254 break;
3255
3256 case HCI_KEYPRESS_COMPLETED:
3257 return;
3258 }
3259
3260 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3261 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3262 conn->dst_type, conn->passkey_notify,
3263 conn->passkey_entered);
3264}
3265
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003266static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3267 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003268{
3269 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3270 struct hci_conn *conn;
3271
3272 BT_DBG("%s", hdev->name);
3273
3274 hci_dev_lock(hdev);
3275
3276 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003277 if (!conn)
3278 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003279
Johan Hedberg2a611692011-02-19 12:06:00 -03003280 /* To avoid duplicate auth_failed events to user space we check
3281 * the HCI_CONN_AUTH_PEND flag which will be set if we
3282 * initiated the authentication. A traditional auth_complete
3283 * event gets always produced as initiator and is also mapped to
3284 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003285 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003286 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003287 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003288
3289 hci_conn_put(conn);
3290
3291unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003292 hci_dev_unlock(hdev);
3293}
3294
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003295static void hci_remote_host_features_evt(struct hci_dev *hdev,
3296 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003297{
3298 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3299 struct inquiry_entry *ie;
3300
3301 BT_DBG("%s", hdev->name);
3302
3303 hci_dev_lock(hdev);
3304
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003305 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3306 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003307 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003308
3309 hci_dev_unlock(hdev);
3310}
3311
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003312static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3313 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003314{
3315 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3316 struct oob_data *data;
3317
3318 BT_DBG("%s", hdev->name);
3319
3320 hci_dev_lock(hdev);
3321
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003322 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003323 goto unlock;
3324
Szymon Janc2763eda2011-03-22 13:12:22 +01003325 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3326 if (data) {
3327 struct hci_cp_remote_oob_data_reply cp;
3328
3329 bacpy(&cp.bdaddr, &ev->bdaddr);
3330 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3331 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3332
3333 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003334 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003335 } else {
3336 struct hci_cp_remote_oob_data_neg_reply cp;
3337
3338 bacpy(&cp.bdaddr, &ev->bdaddr);
3339 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003340 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003341 }
3342
Szymon Jance1ba1f12011-04-06 13:01:59 +02003343unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003344 hci_dev_unlock(hdev);
3345}
3346
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003347static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3348 struct sk_buff *skb)
3349{
3350 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3351 struct hci_conn *hcon, *bredr_hcon;
3352
3353 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3354 ev->status);
3355
3356 hci_dev_lock(hdev);
3357
3358 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3359 if (!hcon) {
3360 hci_dev_unlock(hdev);
3361 return;
3362 }
3363
3364 if (ev->status) {
3365 hci_conn_del(hcon);
3366 hci_dev_unlock(hdev);
3367 return;
3368 }
3369
3370 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3371
3372 hcon->state = BT_CONNECTED;
3373 bacpy(&hcon->dst, &bredr_hcon->dst);
3374
3375 hci_conn_hold(hcon);
3376 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3377 hci_conn_put(hcon);
3378
3379 hci_conn_hold_device(hcon);
3380 hci_conn_add_sysfs(hcon);
3381
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003382 amp_physical_cfm(bredr_hcon, hcon);
3383
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003384 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003385}
3386
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003387static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3388{
3389 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3390 struct hci_conn *hcon;
3391 struct hci_chan *hchan;
3392 struct amp_mgr *mgr;
3393
3394 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3395 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3396 ev->status);
3397
3398 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3399 if (!hcon)
3400 return;
3401
3402 /* Create AMP hchan */
3403 hchan = hci_chan_create(hcon);
3404 if (!hchan)
3405 return;
3406
3407 hchan->handle = le16_to_cpu(ev->handle);
3408
3409 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3410
3411 mgr = hcon->amp_mgr;
3412 if (mgr && mgr->bredr_chan) {
3413 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3414
3415 l2cap_chan_lock(bredr_chan);
3416
3417 bredr_chan->conn->mtu = hdev->block_mtu;
3418 l2cap_logical_cfm(bredr_chan, hchan, 0);
3419 hci_conn_hold(hcon);
3420
3421 l2cap_chan_unlock(bredr_chan);
3422 }
3423}
3424
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003425static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3426 struct sk_buff *skb)
3427{
3428 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3429 struct hci_chan *hchan;
3430
3431 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3432 le16_to_cpu(ev->handle), ev->status);
3433
3434 if (ev->status)
3435 return;
3436
3437 hci_dev_lock(hdev);
3438
3439 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3440 if (!hchan)
3441 goto unlock;
3442
3443 amp_destroy_logical_link(hchan, ev->reason);
3444
3445unlock:
3446 hci_dev_unlock(hdev);
3447}
3448
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003449static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3450 struct sk_buff *skb)
3451{
3452 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3453 struct hci_conn *hcon;
3454
3455 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3456
3457 if (ev->status)
3458 return;
3459
3460 hci_dev_lock(hdev);
3461
3462 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3463 if (hcon) {
3464 hcon->state = BT_CLOSED;
3465 hci_conn_del(hcon);
3466 }
3467
3468 hci_dev_unlock(hdev);
3469}
3470
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003471static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003472{
3473 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3474 struct hci_conn *conn;
3475
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003476 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003477
3478 hci_dev_lock(hdev);
3479
Andre Guedesb47a09b2012-07-27 15:10:15 -03003480 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003481 if (!conn) {
3482 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3483 if (!conn) {
3484 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003485 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003486 }
Andre Guedes29b79882011-05-31 14:20:54 -03003487
3488 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003489
3490 if (ev->role == LE_CONN_ROLE_MASTER) {
3491 conn->out = true;
3492 conn->link_mode |= HCI_LM_MASTER;
3493 }
Ville Tervob62f3282011-02-10 22:38:50 -03003494 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003495
Andre Guedescd17dec2012-07-27 15:10:16 -03003496 if (ev->status) {
3497 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3498 conn->dst_type, ev->status);
3499 hci_proto_connect_cfm(conn, ev->status);
3500 conn->state = BT_CLOSED;
3501 hci_conn_del(conn);
3502 goto unlock;
3503 }
3504
Johan Hedbergb644ba32012-01-17 21:48:47 +02003505 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3506 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003507 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003508
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003509 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003510 conn->handle = __le16_to_cpu(ev->handle);
3511 conn->state = BT_CONNECTED;
3512
3513 hci_conn_hold_device(conn);
3514 hci_conn_add_sysfs(conn);
3515
3516 hci_proto_connect_cfm(conn, ev->status);
3517
3518unlock:
3519 hci_dev_unlock(hdev);
3520}
3521
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003522static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003523{
Andre Guedese95beb42011-09-26 20:48:35 -03003524 u8 num_reports = skb->data[0];
3525 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003526 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003527
Andre Guedese95beb42011-09-26 20:48:35 -03003528 while (num_reports--) {
3529 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003530
Andre Guedes3c9e9192012-01-10 18:20:50 -03003531 rssi = ev->data[ev->length];
3532 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003533 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003534
Andre Guedese95beb42011-09-26 20:48:35 -03003535 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003536 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003537}
3538
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003539static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003540{
3541 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3542 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003543 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003544 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003545 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003546
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003547 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003548
3549 hci_dev_lock(hdev);
3550
3551 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003552 if (conn == NULL)
3553 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003554
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003555 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3556 if (ltk == NULL)
3557 goto not_found;
3558
3559 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003560 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003561
3562 if (ltk->authenticated)
3563 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003564
3565 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3566
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003567 if (ltk->type & HCI_SMP_STK) {
3568 list_del(&ltk->list);
3569 kfree(ltk);
3570 }
3571
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003572 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003573
3574 return;
3575
3576not_found:
3577 neg.handle = ev->handle;
3578 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3579 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003580}
3581
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003582static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003583{
3584 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3585
3586 skb_pull(skb, sizeof(*le_ev));
3587
3588 switch (le_ev->subevent) {
3589 case HCI_EV_LE_CONN_COMPLETE:
3590 hci_le_conn_complete_evt(hdev, skb);
3591 break;
3592
Andre Guedes9aa04c92011-05-26 16:23:51 -03003593 case HCI_EV_LE_ADVERTISING_REPORT:
3594 hci_le_adv_report_evt(hdev, skb);
3595 break;
3596
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003597 case HCI_EV_LE_LTK_REQ:
3598 hci_le_ltk_request_evt(hdev, skb);
3599 break;
3600
Ville Tervofcd89c02011-02-10 22:38:47 -03003601 default:
3602 break;
3603 }
3604}
3605
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003606static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3607{
3608 struct hci_ev_channel_selected *ev = (void *) skb->data;
3609 struct hci_conn *hcon;
3610
3611 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3612
3613 skb_pull(skb, sizeof(*ev));
3614
3615 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3616 if (!hcon)
3617 return;
3618
3619 amp_read_loc_assoc_final_data(hdev, hcon);
3620}
3621
Linus Torvalds1da177e2005-04-16 15:20:36 -07003622void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3623{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003624 struct hci_event_hdr *hdr = (void *) skb->data;
3625 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003626
3627 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3628
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003629 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003630 case HCI_EV_INQUIRY_COMPLETE:
3631 hci_inquiry_complete_evt(hdev, skb);
3632 break;
3633
3634 case HCI_EV_INQUIRY_RESULT:
3635 hci_inquiry_result_evt(hdev, skb);
3636 break;
3637
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003638 case HCI_EV_CONN_COMPLETE:
3639 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003640 break;
3641
Linus Torvalds1da177e2005-04-16 15:20:36 -07003642 case HCI_EV_CONN_REQUEST:
3643 hci_conn_request_evt(hdev, skb);
3644 break;
3645
Linus Torvalds1da177e2005-04-16 15:20:36 -07003646 case HCI_EV_DISCONN_COMPLETE:
3647 hci_disconn_complete_evt(hdev, skb);
3648 break;
3649
Linus Torvalds1da177e2005-04-16 15:20:36 -07003650 case HCI_EV_AUTH_COMPLETE:
3651 hci_auth_complete_evt(hdev, skb);
3652 break;
3653
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003654 case HCI_EV_REMOTE_NAME:
3655 hci_remote_name_evt(hdev, skb);
3656 break;
3657
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658 case HCI_EV_ENCRYPT_CHANGE:
3659 hci_encrypt_change_evt(hdev, skb);
3660 break;
3661
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003662 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3663 hci_change_link_key_complete_evt(hdev, skb);
3664 break;
3665
3666 case HCI_EV_REMOTE_FEATURES:
3667 hci_remote_features_evt(hdev, skb);
3668 break;
3669
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003670 case HCI_EV_CMD_COMPLETE:
3671 hci_cmd_complete_evt(hdev, skb);
3672 break;
3673
3674 case HCI_EV_CMD_STATUS:
3675 hci_cmd_status_evt(hdev, skb);
3676 break;
3677
3678 case HCI_EV_ROLE_CHANGE:
3679 hci_role_change_evt(hdev, skb);
3680 break;
3681
3682 case HCI_EV_NUM_COMP_PKTS:
3683 hci_num_comp_pkts_evt(hdev, skb);
3684 break;
3685
3686 case HCI_EV_MODE_CHANGE:
3687 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003688 break;
3689
3690 case HCI_EV_PIN_CODE_REQ:
3691 hci_pin_code_request_evt(hdev, skb);
3692 break;
3693
3694 case HCI_EV_LINK_KEY_REQ:
3695 hci_link_key_request_evt(hdev, skb);
3696 break;
3697
3698 case HCI_EV_LINK_KEY_NOTIFY:
3699 hci_link_key_notify_evt(hdev, skb);
3700 break;
3701
3702 case HCI_EV_CLOCK_OFFSET:
3703 hci_clock_offset_evt(hdev, skb);
3704 break;
3705
Marcel Holtmanna8746412008-07-14 20:13:46 +02003706 case HCI_EV_PKT_TYPE_CHANGE:
3707 hci_pkt_type_change_evt(hdev, skb);
3708 break;
3709
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003710 case HCI_EV_PSCAN_REP_MODE:
3711 hci_pscan_rep_mode_evt(hdev, skb);
3712 break;
3713
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003714 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3715 hci_inquiry_result_with_rssi_evt(hdev, skb);
3716 break;
3717
3718 case HCI_EV_REMOTE_EXT_FEATURES:
3719 hci_remote_ext_features_evt(hdev, skb);
3720 break;
3721
3722 case HCI_EV_SYNC_CONN_COMPLETE:
3723 hci_sync_conn_complete_evt(hdev, skb);
3724 break;
3725
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003726 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3727 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003728 break;
3729
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003730 case HCI_EV_KEY_REFRESH_COMPLETE:
3731 hci_key_refresh_complete_evt(hdev, skb);
3732 break;
3733
Marcel Holtmann04936842008-07-14 20:13:48 +02003734 case HCI_EV_IO_CAPA_REQUEST:
3735 hci_io_capa_request_evt(hdev, skb);
3736 break;
3737
Johan Hedberg03b555e2011-01-04 15:40:05 +02003738 case HCI_EV_IO_CAPA_REPLY:
3739 hci_io_capa_reply_evt(hdev, skb);
3740 break;
3741
Johan Hedberga5c29682011-02-19 12:05:57 -03003742 case HCI_EV_USER_CONFIRM_REQUEST:
3743 hci_user_confirm_request_evt(hdev, skb);
3744 break;
3745
Brian Gix1143d452011-11-23 08:28:34 -08003746 case HCI_EV_USER_PASSKEY_REQUEST:
3747 hci_user_passkey_request_evt(hdev, skb);
3748 break;
3749
Johan Hedberg92a25252012-09-06 18:39:26 +03003750 case HCI_EV_USER_PASSKEY_NOTIFY:
3751 hci_user_passkey_notify_evt(hdev, skb);
3752 break;
3753
3754 case HCI_EV_KEYPRESS_NOTIFY:
3755 hci_keypress_notify_evt(hdev, skb);
3756 break;
3757
Marcel Holtmann04936842008-07-14 20:13:48 +02003758 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3759 hci_simple_pair_complete_evt(hdev, skb);
3760 break;
3761
Marcel Holtmann41a96212008-07-14 20:13:48 +02003762 case HCI_EV_REMOTE_HOST_FEATURES:
3763 hci_remote_host_features_evt(hdev, skb);
3764 break;
3765
Ville Tervofcd89c02011-02-10 22:38:47 -03003766 case HCI_EV_LE_META:
3767 hci_le_meta_evt(hdev, skb);
3768 break;
3769
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003770 case HCI_EV_CHANNEL_SELECTED:
3771 hci_chan_selected_evt(hdev, skb);
3772 break;
3773
Szymon Janc2763eda2011-03-22 13:12:22 +01003774 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3775 hci_remote_oob_data_request_evt(hdev, skb);
3776 break;
3777
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003778 case HCI_EV_PHY_LINK_COMPLETE:
3779 hci_phy_link_complete_evt(hdev, skb);
3780 break;
3781
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003782 case HCI_EV_LOGICAL_LINK_COMPLETE:
3783 hci_loglink_complete_evt(hdev, skb);
3784 break;
3785
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003786 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3787 hci_disconn_loglink_complete_evt(hdev, skb);
3788 break;
3789
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003790 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3791 hci_disconn_phylink_complete_evt(hdev, skb);
3792 break;
3793
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003794 case HCI_EV_NUM_COMP_BLOCKS:
3795 hci_num_comp_blocks_evt(hdev, skb);
3796 break;
3797
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003798 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003799 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003800 break;
3801 }
3802
3803 kfree_skb(skb);
3804 hdev->stat.evt_rx++;
3805}