blob: 27f66dc88c9b75c3c6f31f07873c168a61574e78 [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 Guedes82f47852013-04-30 15:29:34 -030043 if (status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020044 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
Andre Guedes89352e72011-11-04 14:16:53 -030046 clear_bit(HCI_INQUIRY, &hdev->flags);
Andre Guedes3e13fa12013-03-27 20:04:56 -030047 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
48 wake_up_bit(&hdev->flags, HCI_INQUIRY);
Andre Guedes89352e72011-11-04 14:16:53 -030049
Marcel Holtmanna9de9242007-10-20 13:33:56 +020050 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051}
52
Andre Guedes4d934832012-03-21 00:03:35 -030053static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
54{
55 __u8 status = *((__u8 *) skb->data);
56
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030057 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030058
59 if (status)
60 return;
61
62 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030063}
64
Marcel Holtmanna9de9242007-10-20 13:33:56 +020065static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070066{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020067 __u8 status = *((__u8 *) skb->data);
68
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030069 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020070
71 if (status)
72 return;
73
Andre Guedesae854a72012-03-21 00:03:36 -030074 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
75
Marcel Holtmanna9de9242007-10-20 13:33:56 +020076 hci_conn_check_pending(hdev);
77}
78
Gustavo Padovan807deac2012-05-17 00:36:24 -030079static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
80 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020081{
82 BT_DBG("%s", hdev->name);
83}
84
85static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
86{
87 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030090 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
Marcel Holtmanna9de9242007-10-20 13:33:56 +020092 if (rp->status)
93 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
98 if (conn) {
99 if (rp->role)
100 conn->link_mode &= ~HCI_LM_MASTER;
101 else
102 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200104
105 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106}
107
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200108static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
109{
110 struct hci_rp_read_link_policy *rp = (void *) skb->data;
111 struct hci_conn *conn;
112
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300113 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200114
115 if (rp->status)
116 return;
117
118 hci_dev_lock(hdev);
119
120 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
121 if (conn)
122 conn->link_policy = __le16_to_cpu(rp->policy);
123
124 hci_dev_unlock(hdev);
125}
126
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200127static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200129 struct hci_rp_write_link_policy *rp = (void *) skb->data;
130 struct hci_conn *conn;
131 void *sent;
132
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300133 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200134
135 if (rp->status)
136 return;
137
138 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
139 if (!sent)
140 return;
141
142 hci_dev_lock(hdev);
143
144 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200145 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700146 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200147
148 hci_dev_unlock(hdev);
149}
150
Gustavo Padovan807deac2012-05-17 00:36:24 -0300151static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
152 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200153{
154 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
155
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300156 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200157
158 if (rp->status)
159 return;
160
161 hdev->link_policy = __le16_to_cpu(rp->policy);
162}
163
Gustavo Padovan807deac2012-05-17 00:36:24 -0300164static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
165 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200166{
167 __u8 status = *((__u8 *) skb->data);
168 void *sent;
169
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300170 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200171
172 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
173 if (!sent)
174 return;
175
176 if (!status)
177 hdev->link_policy = get_unaligned_le16(sent);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200178}
179
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200180static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
181{
182 __u8 status = *((__u8 *) skb->data);
183
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300184 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200185
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300186 clear_bit(HCI_RESET, &hdev->flags);
187
Johan Hedberga297e972012-02-21 17:55:47 +0200188 /* Reset all non-persistent flags */
Johan Hedberg2cc6fb02013-03-15 17:06:57 -0500189 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
Andre Guedes69775ff2012-02-23 16:50:05 +0200190
191 hdev->discovery.state = DISCOVERY_STOPPED;
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100192 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
193 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100194
195 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
196 hdev->adv_data_len = 0;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200197}
198
199static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
200{
201 __u8 status = *((__u8 *) skb->data);
202 void *sent;
203
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300204 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200205
206 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
207 if (!sent)
208 return;
209
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200210 hci_dev_lock(hdev);
211
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200212 if (test_bit(HCI_MGMT, &hdev->dev_flags))
213 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200214 else if (!status)
215 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200216
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200217 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200218}
219
220static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
221{
222 struct hci_rp_read_local_name *rp = (void *) skb->data;
223
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300224 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200225
226 if (rp->status)
227 return;
228
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200229 if (test_bit(HCI_SETUP, &hdev->dev_flags))
230 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200231}
232
233static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
234{
235 __u8 status = *((__u8 *) skb->data);
236 void *sent;
237
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300238 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200239
240 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
241 if (!sent)
242 return;
243
244 if (!status) {
245 __u8 param = *((__u8 *) sent);
246
247 if (param == AUTH_ENABLED)
248 set_bit(HCI_AUTH, &hdev->flags);
249 else
250 clear_bit(HCI_AUTH, &hdev->flags);
251 }
252
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200253 if (test_bit(HCI_MGMT, &hdev->dev_flags))
254 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200255}
256
257static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
258{
259 __u8 status = *((__u8 *) skb->data);
260 void *sent;
261
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300262 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200263
264 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
265 if (!sent)
266 return;
267
268 if (!status) {
269 __u8 param = *((__u8 *) sent);
270
271 if (param)
272 set_bit(HCI_ENCRYPT, &hdev->flags);
273 else
274 clear_bit(HCI_ENCRYPT, &hdev->flags);
275 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200276}
277
278static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
279{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200280 __u8 param, status = *((__u8 *) skb->data);
281 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200282 void *sent;
283
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300284 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200285
286 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
287 if (!sent)
288 return;
289
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200290 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200291
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200292 hci_dev_lock(hdev);
293
Mikel Astizfa1bd912012-08-09 09:52:29 +0200294 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200295 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200296 hdev->discov_timeout = 0;
297 goto done;
298 }
299
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200300 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
301 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200302
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200303 if (param & SCAN_INQUIRY) {
304 set_bit(HCI_ISCAN, &hdev->flags);
305 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200306 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200307 if (hdev->discov_timeout > 0) {
308 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
309 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300310 to);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200311 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200312 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200313 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200314
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200315 if (param & SCAN_PAGE) {
316 set_bit(HCI_PSCAN, &hdev->flags);
317 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200318 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200319 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200320 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200321
322done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200323 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200324}
325
326static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
327{
328 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
329
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300330 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200331
332 if (rp->status)
333 return;
334
335 memcpy(hdev->dev_class, rp->dev_class, 3);
336
337 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300338 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200339}
340
341static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
342{
343 __u8 status = *((__u8 *) skb->data);
344 void *sent;
345
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300346 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200347
348 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
349 if (!sent)
350 return;
351
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100352 hci_dev_lock(hdev);
353
354 if (status == 0)
355 memcpy(hdev->dev_class, sent, 3);
356
357 if (test_bit(HCI_MGMT, &hdev->dev_flags))
358 mgmt_set_class_of_dev_complete(hdev, sent, status);
359
360 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200361}
362
363static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
364{
365 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200367
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300368 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200369
370 if (rp->status)
371 return;
372
373 setting = __le16_to_cpu(rp->voice_setting);
374
Marcel Holtmannf383f272008-07-14 20:13:47 +0200375 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200376 return;
377
378 hdev->voice_setting = setting;
379
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300380 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200381
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200382 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200383 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384}
385
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300386static void hci_cc_write_voice_setting(struct hci_dev *hdev,
387 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200388{
389 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200390 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 void *sent;
392
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300393 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394
Marcel Holtmannf383f272008-07-14 20:13:47 +0200395 if (status)
396 return;
397
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200398 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
399 if (!sent)
400 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401
Marcel Holtmannf383f272008-07-14 20:13:47 +0200402 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403
Marcel Holtmannf383f272008-07-14 20:13:47 +0200404 if (hdev->voice_setting == setting)
405 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
Marcel Holtmannf383f272008-07-14 20:13:47 +0200407 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300409 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200411 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200412 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413}
414
Marcel Holtmann333140b2008-07-14 20:13:48 +0200415static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
416{
417 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300418 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200419
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300420 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200421
Marcel Holtmann333140b2008-07-14 20:13:48 +0200422 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
423 if (!sent)
424 return;
425
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300426 if (!status) {
427 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300428 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300429 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300430 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300431 }
432
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200433 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300434 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200435 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300436 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200437 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
438 else
439 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
440 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200441}
442
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200443static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
444{
445 struct hci_rp_read_local_version *rp = (void *) skb->data;
446
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300447 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200448
449 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200450 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200451
452 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200453 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200454 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200455 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200456 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200457
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300458 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300459 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200460}
461
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300462static void hci_cc_read_local_commands(struct hci_dev *hdev,
463 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200464{
465 struct hci_rp_read_local_commands *rp = (void *) skb->data;
466
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300467 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200468
Johan Hedberg2177bab2013-03-05 20:37:43 +0200469 if (!rp->status)
470 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200471}
472
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300473static void hci_cc_read_local_features(struct hci_dev *hdev,
474 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200475{
476 struct hci_rp_read_local_features *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
480 if (rp->status)
481 return;
482
483 memcpy(hdev->features, rp->features, 8);
484
485 /* Adjust default settings according to features
486 * supported by device. */
487
Johan Hedbergcad718e2013-04-17 15:00:51 +0300488 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200489 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
490
Johan Hedbergcad718e2013-04-17 15:00:51 +0300491 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200492 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
493
Johan Hedbergcad718e2013-04-17 15:00:51 +0300494 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200495 hdev->pkt_type |= (HCI_HV2);
496 hdev->esco_type |= (ESCO_HV2);
497 }
498
Johan Hedbergcad718e2013-04-17 15:00:51 +0300499 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200500 hdev->pkt_type |= (HCI_HV3);
501 hdev->esco_type |= (ESCO_HV3);
502 }
503
Andre Guedes45db810f2012-07-24 15:03:49 -0300504 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200505 hdev->esco_type |= (ESCO_EV3);
506
Johan Hedbergcad718e2013-04-17 15:00:51 +0300507 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200508 hdev->esco_type |= (ESCO_EV4);
509
Johan Hedbergcad718e2013-04-17 15:00:51 +0300510 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200511 hdev->esco_type |= (ESCO_EV5);
512
Johan Hedbergcad718e2013-04-17 15:00:51 +0300513 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100514 hdev->esco_type |= (ESCO_2EV3);
515
Johan Hedbergcad718e2013-04-17 15:00:51 +0300516 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100517 hdev->esco_type |= (ESCO_3EV3);
518
Johan Hedbergcad718e2013-04-17 15:00:51 +0300519 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100520 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
521
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200522 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
Johan Hedbergcad718e2013-04-17 15:00:51 +0300523 hdev->features[0][0], hdev->features[0][1],
524 hdev->features[0][2], hdev->features[0][3],
525 hdev->features[0][4], hdev->features[0][5],
526 hdev->features[0][6], hdev->features[0][7]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200527}
528
Andre Guedes971e3a42011-06-30 19:20:52 -0300529static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300530 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300531{
532 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
533
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300534 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300535
536 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200537 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300538
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300539 hdev->max_page = rp->max_page;
540
Johan Hedbergcad718e2013-04-17 15:00:51 +0300541 if (rp->page < HCI_MAX_PAGES)
542 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300543}
544
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200545static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300546 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200547{
548 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
549
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300550 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200551
Johan Hedberg42c6b122013-03-05 20:37:49 +0200552 if (!rp->status)
553 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200554}
555
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200556static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
557{
558 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
559
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300560 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200561
562 if (rp->status)
563 return;
564
565 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
566 hdev->sco_mtu = rp->sco_mtu;
567 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
568 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
569
570 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
571 hdev->sco_mtu = 64;
572 hdev->sco_pkts = 8;
573 }
574
575 hdev->acl_cnt = hdev->acl_pkts;
576 hdev->sco_cnt = hdev->sco_pkts;
577
Gustavo Padovan807deac2012-05-17 00:36:24 -0300578 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
579 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200580}
581
582static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
583{
584 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
585
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300586 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200587
588 if (!rp->status)
589 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200590}
591
Johan Hedbergf332ec62013-03-15 17:07:11 -0500592static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
593 struct sk_buff *skb)
594{
595 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
596
597 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
598
599 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
600 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
601 hdev->page_scan_window = __le16_to_cpu(rp->window);
602 }
603}
604
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500605static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
606 struct sk_buff *skb)
607{
608 u8 status = *((u8 *) skb->data);
609 struct hci_cp_write_page_scan_activity *sent;
610
611 BT_DBG("%s status 0x%2.2x", hdev->name, status);
612
613 if (status)
614 return;
615
616 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
617 if (!sent)
618 return;
619
620 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
621 hdev->page_scan_window = __le16_to_cpu(sent->window);
622}
623
Johan Hedbergf332ec62013-03-15 17:07:11 -0500624static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
625 struct sk_buff *skb)
626{
627 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
628
629 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
630
631 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
632 hdev->page_scan_type = rp->type;
633}
634
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500635static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
636 struct sk_buff *skb)
637{
638 u8 status = *((u8 *) skb->data);
639 u8 *type;
640
641 BT_DBG("%s status 0x%2.2x", hdev->name, status);
642
643 if (status)
644 return;
645
646 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
647 if (type)
648 hdev->page_scan_type = *type;
649}
650
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200651static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300652 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200653{
654 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
655
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300656 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200657
658 if (rp->status)
659 return;
660
661 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
662 hdev->block_len = __le16_to_cpu(rp->block_len);
663 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
664
665 hdev->block_cnt = hdev->num_blocks;
666
667 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300668 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200669}
670
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300671static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300672 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300673{
674 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
675
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300676 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300677
678 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300679 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300680
681 hdev->amp_status = rp->amp_status;
682 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
683 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
684 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
685 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
686 hdev->amp_type = rp->amp_type;
687 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
688 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
689 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
690 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
691
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300692a2mp_rsp:
693 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300694}
695
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300696static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
697 struct sk_buff *skb)
698{
699 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
700 struct amp_assoc *assoc = &hdev->loc_assoc;
701 size_t rem_len, frag_len;
702
703 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
704
705 if (rp->status)
706 goto a2mp_rsp;
707
708 frag_len = skb->len - sizeof(*rp);
709 rem_len = __le16_to_cpu(rp->rem_len);
710
711 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300712 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300713
714 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
715 assoc->offset += frag_len;
716
717 /* Read other fragments */
718 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
719
720 return;
721 }
722
723 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
724 assoc->len = assoc->offset + rem_len;
725 assoc->offset = 0;
726
727a2mp_rsp:
728 /* Send A2MP Rsp when all fragments are received */
729 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300730 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300731}
732
Johan Hedbergd5859e22011-01-25 01:19:58 +0200733static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300734 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200735{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700736 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200737
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300738 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200739
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700740 if (!rp->status)
741 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200742}
743
Johan Hedberg980e1a52011-01-22 06:10:07 +0200744static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
745{
746 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
747 struct hci_cp_pin_code_reply *cp;
748 struct hci_conn *conn;
749
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300750 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200751
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200752 hci_dev_lock(hdev);
753
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200754 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200755 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200756
Mikel Astizfa1bd912012-08-09 09:52:29 +0200757 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200758 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200759
760 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
761 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200762 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200763
764 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
765 if (conn)
766 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200767
768unlock:
769 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200770}
771
772static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
773{
774 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
775
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300776 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200777
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200778 hci_dev_lock(hdev);
779
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200780 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200781 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300782 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200783
784 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200785}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200786
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300787static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
788 struct sk_buff *skb)
789{
790 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
791
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300792 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300793
794 if (rp->status)
795 return;
796
797 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
798 hdev->le_pkts = rp->le_max_pkt;
799
800 hdev->le_cnt = hdev->le_pkts;
801
802 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300803}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200804
Johan Hedberg60e77322013-01-22 14:01:59 +0200805static void hci_cc_le_read_local_features(struct hci_dev *hdev,
806 struct sk_buff *skb)
807{
808 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
809
810 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
811
812 if (!rp->status)
813 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200814}
815
Johan Hedberg8fa19092012-10-19 20:57:49 +0300816static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
817 struct sk_buff *skb)
818{
819 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
820
821 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
822
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500823 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300824 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300825}
826
Johan Hedberga5c29682011-02-19 12:05:57 -0300827static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
828{
829 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
830
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300831 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300832
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200833 hci_dev_lock(hdev);
834
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200835 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300836 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
837 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200838
839 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300840}
841
842static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300843 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300844{
845 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
846
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300847 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300848
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200849 hci_dev_lock(hdev);
850
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200851 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200852 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300853 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200854
855 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300856}
857
Brian Gix1143d452011-11-23 08:28:34 -0800858static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
859{
860 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
861
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300862 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800863
864 hci_dev_lock(hdev);
865
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200866 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200867 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300868 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800869
870 hci_dev_unlock(hdev);
871}
872
873static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300874 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800875{
876 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
877
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300878 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800879
880 hci_dev_lock(hdev);
881
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200882 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800883 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300884 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800885
886 hci_dev_unlock(hdev);
887}
888
Szymon Jancc35938b2011-03-22 13:12:21 +0100889static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300890 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100891{
892 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
893
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300894 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100895
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200896 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200897 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100898 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200899 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100900}
901
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100902static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
903{
904 __u8 *sent, status = *((__u8 *) skb->data);
905
906 BT_DBG("%s status 0x%2.2x", hdev->name, status);
907
908 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
909 if (!sent)
910 return;
911
912 hci_dev_lock(hdev);
913
914 if (!status) {
915 if (*sent)
916 set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
917 else
918 clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
919 }
920
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500921 if (!test_bit(HCI_INIT, &hdev->flags)) {
922 struct hci_request req;
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100923
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500924 hci_req_init(&req, hdev);
925 hci_update_ad(&req);
926 hci_req_run(&req, NULL);
927 }
928
929 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100930}
931
Andre Guedes07f7fa52011-12-02 21:13:31 +0900932static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
933{
934 __u8 status = *((__u8 *) skb->data);
935
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300936 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300937
Andre Guedes07f7fa52011-12-02 21:13:31 +0900938}
939
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300940static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300941 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300942{
943 struct hci_cp_le_set_scan_enable *cp;
944 __u8 status = *((__u8 *) skb->data);
945
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300946 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300947
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300948 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
949 if (!cp)
950 return;
951
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200952 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -0300953 case LE_SCAN_ENABLE:
Andre Guedesfef52342013-04-30 15:29:29 -0300954 if (status)
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300955 return;
956
Andre Guedesd23264a2011-11-25 20:53:38 -0300957 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200958 break;
959
Andre Guedes76a388b2013-04-04 20:21:02 -0300960 case LE_SCAN_DISABLE:
Andre Guedes82f47852013-04-30 15:29:34 -0300961 if (status)
Andre Guedes7ba8b4b2012-02-03 17:47:59 -0300962 return;
963
Andre Guedesd23264a2011-11-25 20:53:38 -0300964 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200965 break;
966
967 default:
968 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
969 break;
Andre Guedes35815082011-05-26 16:23:53 -0300970 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300971}
972
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200973static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
974 struct sk_buff *skb)
975{
976 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
977
978 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
979
980 if (!rp->status)
981 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200982}
983
Johan Hedberg9b008c02013-01-22 14:02:01 +0200984static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
985 struct sk_buff *skb)
986{
987 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
988
989 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
990
991 if (!rp->status)
992 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +0200993}
994
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300995static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
996 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -0300997{
Johan Hedberg06199cf2012-02-22 16:37:11 +0200998 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -0300999 __u8 status = *((__u8 *) skb->data);
1000
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001001 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001002
Johan Hedberg06199cf2012-02-22 16:37:11 +02001003 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001004 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001005 return;
1006
Johan Hedberg8f984df2012-02-28 01:07:22 +02001007 if (!status) {
1008 if (sent->le)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001009 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001010 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001011 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001012
1013 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001014 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001015 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001016 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001017 }
1018
1019 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001020 !test_bit(HCI_INIT, &hdev->flags))
Johan Hedberg8f984df2012-02-28 01:07:22 +02001021 mgmt_le_enable_complete(hdev, sent->le, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001022}
1023
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001024static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1025 struct sk_buff *skb)
1026{
1027 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1028
1029 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1030 hdev->name, rp->status, rp->phy_handle);
1031
1032 if (rp->status)
1033 return;
1034
1035 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1036}
1037
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001038static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001039{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001040 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001041
1042 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001043 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001044 return;
1045 }
1046
Andre Guedes89352e72011-11-04 14:16:53 -03001047 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001048}
1049
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001050static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001052 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001055 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001056
1057 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 if (!cp)
1059 return;
1060
1061 hci_dev_lock(hdev);
1062
1063 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1064
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001065 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066
1067 if (status) {
1068 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001069 if (status != 0x0c || conn->attempt > 2) {
1070 conn->state = BT_CLOSED;
1071 hci_proto_connect_cfm(conn, status);
1072 hci_conn_del(conn);
1073 } else
1074 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 }
1076 } else {
1077 if (!conn) {
1078 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1079 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001080 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 conn->link_mode |= HCI_LM_MASTER;
1082 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001083 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 }
1085 }
1086
1087 hci_dev_unlock(hdev);
1088}
1089
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001090static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001092 struct hci_cp_add_sco *cp;
1093 struct hci_conn *acl, *sco;
1094 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001096 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001097
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001098 if (!status)
1099 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001101 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1102 if (!cp)
1103 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001105 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001107 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001108
1109 hci_dev_lock(hdev);
1110
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001111 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001112 if (acl) {
1113 sco = acl->link;
1114 if (sco) {
1115 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001116
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001117 hci_proto_connect_cfm(sco, status);
1118 hci_conn_del(sco);
1119 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001120 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001121
1122 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123}
1124
Marcel Holtmannf8558552008-07-14 20:13:49 +02001125static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1126{
1127 struct hci_cp_auth_requested *cp;
1128 struct hci_conn *conn;
1129
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001130 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001131
1132 if (!status)
1133 return;
1134
1135 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1136 if (!cp)
1137 return;
1138
1139 hci_dev_lock(hdev);
1140
1141 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1142 if (conn) {
1143 if (conn->state == BT_CONFIG) {
1144 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001145 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001146 }
1147 }
1148
1149 hci_dev_unlock(hdev);
1150}
1151
1152static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1153{
1154 struct hci_cp_set_conn_encrypt *cp;
1155 struct hci_conn *conn;
1156
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001157 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001158
1159 if (!status)
1160 return;
1161
1162 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1163 if (!cp)
1164 return;
1165
1166 hci_dev_lock(hdev);
1167
1168 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1169 if (conn) {
1170 if (conn->state == BT_CONFIG) {
1171 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001172 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001173 }
1174 }
1175
1176 hci_dev_unlock(hdev);
1177}
1178
Johan Hedberg127178d2010-11-18 22:22:29 +02001179static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001180 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001181{
Johan Hedberg392599b2010-11-18 22:22:28 +02001182 if (conn->state != BT_CONFIG || !conn->out)
1183 return 0;
1184
Johan Hedberg765c2a92011-01-19 12:06:52 +05301185 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001186 return 0;
1187
1188 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001189 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001190 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1191 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001192 return 0;
1193
Johan Hedberg392599b2010-11-18 22:22:28 +02001194 return 1;
1195}
1196
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001197static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001198 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001199{
1200 struct hci_cp_remote_name_req cp;
1201
1202 memset(&cp, 0, sizeof(cp));
1203
1204 bacpy(&cp.bdaddr, &e->data.bdaddr);
1205 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1206 cp.pscan_mode = e->data.pscan_mode;
1207 cp.clock_offset = e->data.clock_offset;
1208
1209 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1210}
1211
Johan Hedbergb644ba32012-01-17 21:48:47 +02001212static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001213{
1214 struct discovery_state *discov = &hdev->discovery;
1215 struct inquiry_entry *e;
1216
Johan Hedbergb644ba32012-01-17 21:48:47 +02001217 if (list_empty(&discov->resolve))
1218 return false;
1219
1220 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001221 if (!e)
1222 return false;
1223
Johan Hedbergb644ba32012-01-17 21:48:47 +02001224 if (hci_resolve_name(hdev, e) == 0) {
1225 e->name_state = NAME_PENDING;
1226 return true;
1227 }
1228
1229 return false;
1230}
1231
1232static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001233 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001234{
1235 struct discovery_state *discov = &hdev->discovery;
1236 struct inquiry_entry *e;
1237
1238 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001239 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1240 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001241
1242 if (discov->state == DISCOVERY_STOPPED)
1243 return;
1244
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001245 if (discov->state == DISCOVERY_STOPPING)
1246 goto discov_complete;
1247
1248 if (discov->state != DISCOVERY_RESOLVING)
1249 return;
1250
1251 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001252 /* If the device was not found in a list of found devices names of which
1253 * are pending. there is no need to continue resolving a next name as it
1254 * will be done upon receiving another Remote Name Request Complete
1255 * Event */
1256 if (!e)
1257 return;
1258
1259 list_del(&e->list);
1260 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001261 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001262 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1263 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001264 } else {
1265 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001266 }
1267
Johan Hedbergb644ba32012-01-17 21:48:47 +02001268 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001269 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001270
1271discov_complete:
1272 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1273}
1274
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001275static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1276{
Johan Hedberg127178d2010-11-18 22:22:29 +02001277 struct hci_cp_remote_name_req *cp;
1278 struct hci_conn *conn;
1279
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001280 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001281
1282 /* If successful wait for the name req complete event before
1283 * checking for the need to do authentication */
1284 if (!status)
1285 return;
1286
1287 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1288 if (!cp)
1289 return;
1290
1291 hci_dev_lock(hdev);
1292
1293 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001294
1295 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1296 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1297
Johan Hedberg79c6c702011-04-28 11:28:55 -07001298 if (!conn)
1299 goto unlock;
1300
1301 if (!hci_outgoing_auth_needed(hdev, conn))
1302 goto unlock;
1303
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001304 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001305 struct hci_cp_auth_requested cp;
1306 cp.handle = __cpu_to_le16(conn->handle);
1307 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1308 }
1309
Johan Hedberg79c6c702011-04-28 11:28:55 -07001310unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001311 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001312}
1313
Marcel Holtmann769be972008-07-14 20:13:49 +02001314static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1315{
1316 struct hci_cp_read_remote_features *cp;
1317 struct hci_conn *conn;
1318
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001319 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001320
1321 if (!status)
1322 return;
1323
1324 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1325 if (!cp)
1326 return;
1327
1328 hci_dev_lock(hdev);
1329
1330 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1331 if (conn) {
1332 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001333 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001334 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001335 }
1336 }
1337
1338 hci_dev_unlock(hdev);
1339}
1340
1341static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1342{
1343 struct hci_cp_read_remote_ext_features *cp;
1344 struct hci_conn *conn;
1345
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001346 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001347
1348 if (!status)
1349 return;
1350
1351 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1352 if (!cp)
1353 return;
1354
1355 hci_dev_lock(hdev);
1356
1357 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1358 if (conn) {
1359 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001360 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001361 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001362 }
1363 }
1364
1365 hci_dev_unlock(hdev);
1366}
1367
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001368static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1369{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001370 struct hci_cp_setup_sync_conn *cp;
1371 struct hci_conn *acl, *sco;
1372 __u16 handle;
1373
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001374 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001375
1376 if (!status)
1377 return;
1378
1379 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1380 if (!cp)
1381 return;
1382
1383 handle = __le16_to_cpu(cp->handle);
1384
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001385 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001386
1387 hci_dev_lock(hdev);
1388
1389 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001390 if (acl) {
1391 sco = acl->link;
1392 if (sco) {
1393 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001394
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001395 hci_proto_connect_cfm(sco, status);
1396 hci_conn_del(sco);
1397 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001398 }
1399
1400 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001401}
1402
1403static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1404{
1405 struct hci_cp_sniff_mode *cp;
1406 struct hci_conn *conn;
1407
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001408 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001409
1410 if (!status)
1411 return;
1412
1413 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1414 if (!cp)
1415 return;
1416
1417 hci_dev_lock(hdev);
1418
1419 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001420 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001421 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001422
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001423 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001424 hci_sco_setup(conn, status);
1425 }
1426
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001427 hci_dev_unlock(hdev);
1428}
1429
1430static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1431{
1432 struct hci_cp_exit_sniff_mode *cp;
1433 struct hci_conn *conn;
1434
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001435 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001436
1437 if (!status)
1438 return;
1439
1440 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1441 if (!cp)
1442 return;
1443
1444 hci_dev_lock(hdev);
1445
1446 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001447 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001448 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001449
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001450 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001451 hci_sco_setup(conn, status);
1452 }
1453
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001454 hci_dev_unlock(hdev);
1455}
1456
Johan Hedberg88c3df12012-02-09 14:27:38 +02001457static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1458{
1459 struct hci_cp_disconnect *cp;
1460 struct hci_conn *conn;
1461
1462 if (!status)
1463 return;
1464
1465 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1466 if (!cp)
1467 return;
1468
1469 hci_dev_lock(hdev);
1470
1471 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1472 if (conn)
1473 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001474 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001475
1476 hci_dev_unlock(hdev);
1477}
1478
Ville Tervofcd89c02011-02-10 22:38:47 -03001479static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1480{
Ville Tervofcd89c02011-02-10 22:38:47 -03001481 struct hci_conn *conn;
1482
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001483 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Ville Tervofcd89c02011-02-10 22:38:47 -03001484
Ville Tervofcd89c02011-02-10 22:38:47 -03001485 if (status) {
Andre Guedesf00a06a2012-07-27 15:10:13 -03001486 hci_dev_lock(hdev);
Ville Tervofcd89c02011-02-10 22:38:47 -03001487
Andre Guedes0c95ab72012-07-27 15:10:14 -03001488 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001489 if (!conn) {
1490 hci_dev_unlock(hdev);
1491 return;
1492 }
1493
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001494 BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001495
1496 conn->state = BT_CLOSED;
Andre Guedes0c95ab72012-07-27 15:10:14 -03001497 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Andre Guedesf00a06a2012-07-27 15:10:13 -03001498 conn->dst_type, status);
1499 hci_proto_connect_cfm(conn, status);
1500 hci_conn_del(conn);
1501
1502 hci_dev_unlock(hdev);
1503 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001504}
1505
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001506static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1507{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001508 struct hci_cp_create_phy_link *cp;
1509
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001510 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001511
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001512 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1513 if (!cp)
1514 return;
1515
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001516 hci_dev_lock(hdev);
1517
1518 if (status) {
1519 struct hci_conn *hcon;
1520
1521 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1522 if (hcon)
1523 hci_conn_del(hcon);
1524 } else {
1525 amp_write_remote_assoc(hdev, cp->phy_handle);
1526 }
1527
1528 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001529}
1530
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001531static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1532{
1533 struct hci_cp_accept_phy_link *cp;
1534
1535 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1536
1537 if (status)
1538 return;
1539
1540 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1541 if (!cp)
1542 return;
1543
1544 amp_write_remote_assoc(hdev, cp->phy_handle);
1545}
1546
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001547static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001548{
1549 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001550 struct discovery_state *discov = &hdev->discovery;
1551 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001552
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001553 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001554
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001555 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001556
1557 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1558 return;
1559
Andre Guedes3e13fa12013-03-27 20:04:56 -03001560 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1561 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1562
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001563 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001564 return;
1565
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001566 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001567
Andre Guedes343f9352012-02-17 20:39:37 -03001568 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001569 goto unlock;
1570
1571 if (list_empty(&discov->resolve)) {
1572 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1573 goto unlock;
1574 }
1575
1576 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1577 if (e && hci_resolve_name(hdev, e) == 0) {
1578 e->name_state = NAME_PENDING;
1579 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1580 } else {
1581 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1582 }
1583
1584unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001585 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001586}
1587
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001588static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001590 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001591 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592 int num_rsp = *((__u8 *) skb->data);
1593
1594 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1595
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001596 if (!num_rsp)
1597 return;
1598
Andre Guedes1519cc12012-03-21 00:03:38 -03001599 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1600 return;
1601
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001603
Johan Hedberge17acd42011-03-30 23:57:16 +03001604 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001605 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001606
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 bacpy(&data.bdaddr, &info->bdaddr);
1608 data.pscan_rep_mode = info->pscan_rep_mode;
1609 data.pscan_period_mode = info->pscan_period_mode;
1610 data.pscan_mode = info->pscan_mode;
1611 memcpy(data.dev_class, info->dev_class, 3);
1612 data.clock_offset = info->clock_offset;
1613 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001614 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001615
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001616 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001617 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001618 info->dev_class, 0, !name_known, ssp, NULL,
1619 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001621
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 hci_dev_unlock(hdev);
1623}
1624
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001625static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001627 struct hci_ev_conn_complete *ev = (void *) skb->data;
1628 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001630 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001631
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001633
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001634 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001635 if (!conn) {
1636 if (ev->link_type != SCO_LINK)
1637 goto unlock;
1638
1639 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1640 if (!conn)
1641 goto unlock;
1642
1643 conn->type = SCO_LINK;
1644 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001645
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001646 if (!ev->status) {
1647 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001648
1649 if (conn->type == ACL_LINK) {
1650 conn->state = BT_CONFIG;
1651 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001652
1653 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1654 !hci_find_link_key(hdev, &ev->bdaddr))
1655 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1656 else
1657 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001658 } else
1659 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001660
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001661 hci_conn_add_sysfs(conn);
1662
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001663 if (test_bit(HCI_AUTH, &hdev->flags))
1664 conn->link_mode |= HCI_LM_AUTH;
1665
1666 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1667 conn->link_mode |= HCI_LM_ENCRYPT;
1668
1669 /* Get remote features */
1670 if (conn->type == ACL_LINK) {
1671 struct hci_cp_read_remote_features cp;
1672 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001673 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001674 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001675 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001676
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001677 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001678 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001679 struct hci_cp_change_conn_ptype cp;
1680 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001681 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001682 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1683 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001684 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001685 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001686 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001687 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001688 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001689 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001690 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001691
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001692 if (conn->type == ACL_LINK)
1693 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001694
Marcel Holtmann769be972008-07-14 20:13:49 +02001695 if (ev->status) {
1696 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001697 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001698 } else if (ev->link_type != ACL_LINK)
1699 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001700
1701unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001703
1704 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705}
1706
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001707static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001709 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001711 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001713 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001714 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001716 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1717 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718
Szymon Janc138d22e2011-02-17 16:44:23 +01001719 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001720 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001722 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724
1725 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001726
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001727 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1728 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001729 memcpy(ie->data.dev_class, ev->dev_class, 3);
1730
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001731 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1732 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001734 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1735 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001736 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 hci_dev_unlock(hdev);
1738 return;
1739 }
1740 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001741
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001743
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 hci_dev_unlock(hdev);
1745
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001746 if (ev->link_type == ACL_LINK ||
1747 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001748 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001749 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001751 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001753 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1754 cp.role = 0x00; /* Become master */
1755 else
1756 cp.role = 0x01; /* Remain slave */
1757
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001758 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1759 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001760 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001761 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001762 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001763
1764 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001765 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001766
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001767 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1768 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1769 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001770 cp.content_format = cpu_to_le16(hdev->voice_setting);
1771 cp.retrans_effort = 0xff;
1772
1773 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001774 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001775 } else {
1776 conn->state = BT_CONNECT2;
1777 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001778 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 } else {
1780 /* Connection rejected */
1781 struct hci_cp_reject_conn_req cp;
1782
1783 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001784 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001785 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786 }
1787}
1788
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001789static u8 hci_to_mgmt_reason(u8 err)
1790{
1791 switch (err) {
1792 case HCI_ERROR_CONNECTION_TIMEOUT:
1793 return MGMT_DEV_DISCONN_TIMEOUT;
1794 case HCI_ERROR_REMOTE_USER_TERM:
1795 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1796 case HCI_ERROR_REMOTE_POWER_OFF:
1797 return MGMT_DEV_DISCONN_REMOTE;
1798 case HCI_ERROR_LOCAL_HOST_TERM:
1799 return MGMT_DEV_DISCONN_LOCAL_HOST;
1800 default:
1801 return MGMT_DEV_DISCONN_UNKNOWN;
1802 }
1803}
1804
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001805static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001807 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001808 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001810 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 hci_dev_lock(hdev);
1813
Marcel Holtmann04837f62006-07-03 10:02:33 +02001814 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001815 if (!conn)
1816 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001817
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001818 if (ev->status == 0)
1819 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820
Johan Hedbergb644ba32012-01-17 21:48:47 +02001821 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001822 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001823 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001824 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001825 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001826 } else {
1827 u8 reason = hci_to_mgmt_reason(ev->reason);
1828
Johan Hedbergafc747a2012-01-15 18:11:07 +02001829 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001830 conn->dst_type, reason);
1831 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001832 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001833
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001834 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301835 if (conn->type == ACL_LINK && conn->flush_key)
1836 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001837 hci_proto_disconn_cfm(conn, ev->reason);
1838 hci_conn_del(conn);
1839 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001840
1841unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 hci_dev_unlock(hdev);
1843}
1844
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001845static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001846{
1847 struct hci_ev_auth_complete *ev = (void *) skb->data;
1848 struct hci_conn *conn;
1849
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001850 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001851
1852 hci_dev_lock(hdev);
1853
1854 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001855 if (!conn)
1856 goto unlock;
1857
1858 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001859 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001860 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001861 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001862 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001863 conn->link_mode |= HCI_LM_AUTH;
1864 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001865 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001866 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001867 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001868 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001869 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001870
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001871 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1872 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001873
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001874 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001875 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001876 struct hci_cp_set_conn_encrypt cp;
1877 cp.handle = ev->handle;
1878 cp.encrypt = 0x01;
1879 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001880 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001881 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001882 conn->state = BT_CONNECTED;
1883 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001884 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001885 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001886 } else {
1887 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001888
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001889 hci_conn_hold(conn);
1890 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001891 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001892 }
1893
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001894 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001895 if (!ev->status) {
1896 struct hci_cp_set_conn_encrypt cp;
1897 cp.handle = ev->handle;
1898 cp.encrypt = 0x01;
1899 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001900 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001901 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001902 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001903 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001904 }
1905 }
1906
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001907unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001908 hci_dev_unlock(hdev);
1909}
1910
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001911static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001912{
Johan Hedberg127178d2010-11-18 22:22:29 +02001913 struct hci_ev_remote_name *ev = (void *) skb->data;
1914 struct hci_conn *conn;
1915
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001916 BT_DBG("%s", hdev->name);
1917
1918 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001919
1920 hci_dev_lock(hdev);
1921
1922 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001923
1924 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1925 goto check_auth;
1926
1927 if (ev->status == 0)
1928 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001929 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001930 else
1931 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1932
1933check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001934 if (!conn)
1935 goto unlock;
1936
1937 if (!hci_outgoing_auth_needed(hdev, conn))
1938 goto unlock;
1939
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001940 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001941 struct hci_cp_auth_requested cp;
1942 cp.handle = __cpu_to_le16(conn->handle);
1943 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1944 }
1945
Johan Hedberg79c6c702011-04-28 11:28:55 -07001946unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001947 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001948}
1949
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001950static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001951{
1952 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1953 struct hci_conn *conn;
1954
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001955 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001956
1957 hci_dev_lock(hdev);
1958
1959 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1960 if (conn) {
1961 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001962 if (ev->encrypt) {
1963 /* Encryption implies authentication */
1964 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001965 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001966 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001967 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001968 conn->link_mode &= ~HCI_LM_ENCRYPT;
1969 }
1970
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001971 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001972
Gustavo Padovana7d77232012-05-13 03:20:07 -03001973 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03001974 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02001975 hci_conn_drop(conn);
Gustavo Padovana7d77232012-05-13 03:20:07 -03001976 goto unlock;
1977 }
1978
Marcel Holtmannf8558552008-07-14 20:13:49 +02001979 if (conn->state == BT_CONFIG) {
1980 if (!ev->status)
1981 conn->state = BT_CONNECTED;
1982
1983 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001984 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001985 } else
1986 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001987 }
1988
Gustavo Padovana7d77232012-05-13 03:20:07 -03001989unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001990 hci_dev_unlock(hdev);
1991}
1992
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001993static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
1994 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001995{
1996 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1997 struct hci_conn *conn;
1998
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001999 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002000
2001 hci_dev_lock(hdev);
2002
2003 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2004 if (conn) {
2005 if (!ev->status)
2006 conn->link_mode |= HCI_LM_SECURE;
2007
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002008 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002009
2010 hci_key_change_cfm(conn, ev->status);
2011 }
2012
2013 hci_dev_unlock(hdev);
2014}
2015
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002016static void hci_remote_features_evt(struct hci_dev *hdev,
2017 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002018{
2019 struct hci_ev_remote_features *ev = (void *) skb->data;
2020 struct hci_conn *conn;
2021
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002022 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002023
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002024 hci_dev_lock(hdev);
2025
2026 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002027 if (!conn)
2028 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002029
Johan Hedbergccd556f2010-11-10 17:11:51 +02002030 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002031 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002032
2033 if (conn->state != BT_CONFIG)
2034 goto unlock;
2035
2036 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2037 struct hci_cp_read_remote_ext_features cp;
2038 cp.handle = ev->handle;
2039 cp.page = 0x01;
2040 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002041 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002042 goto unlock;
2043 }
2044
Johan Hedberg671267b2012-05-12 16:11:50 -03002045 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002046 struct hci_cp_remote_name_req cp;
2047 memset(&cp, 0, sizeof(cp));
2048 bacpy(&cp.bdaddr, &conn->dst);
2049 cp.pscan_rep_mode = 0x02;
2050 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002051 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2052 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002053 conn->dst_type, 0, NULL, 0,
2054 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002055
Johan Hedberg127178d2010-11-18 22:22:29 +02002056 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002057 conn->state = BT_CONNECTED;
2058 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002059 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002060 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002061
Johan Hedbergccd556f2010-11-10 17:11:51 +02002062unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002063 hci_dev_unlock(hdev);
2064}
2065
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002066static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002067{
2068 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002069 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002070 __u16 opcode;
2071
2072 skb_pull(skb, sizeof(*ev));
2073
2074 opcode = __le16_to_cpu(ev->opcode);
2075
2076 switch (opcode) {
2077 case HCI_OP_INQUIRY_CANCEL:
2078 hci_cc_inquiry_cancel(hdev, skb);
2079 break;
2080
Andre Guedes4d934832012-03-21 00:03:35 -03002081 case HCI_OP_PERIODIC_INQ:
2082 hci_cc_periodic_inq(hdev, skb);
2083 break;
2084
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002085 case HCI_OP_EXIT_PERIODIC_INQ:
2086 hci_cc_exit_periodic_inq(hdev, skb);
2087 break;
2088
2089 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2090 hci_cc_remote_name_req_cancel(hdev, skb);
2091 break;
2092
2093 case HCI_OP_ROLE_DISCOVERY:
2094 hci_cc_role_discovery(hdev, skb);
2095 break;
2096
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002097 case HCI_OP_READ_LINK_POLICY:
2098 hci_cc_read_link_policy(hdev, skb);
2099 break;
2100
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002101 case HCI_OP_WRITE_LINK_POLICY:
2102 hci_cc_write_link_policy(hdev, skb);
2103 break;
2104
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002105 case HCI_OP_READ_DEF_LINK_POLICY:
2106 hci_cc_read_def_link_policy(hdev, skb);
2107 break;
2108
2109 case HCI_OP_WRITE_DEF_LINK_POLICY:
2110 hci_cc_write_def_link_policy(hdev, skb);
2111 break;
2112
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002113 case HCI_OP_RESET:
2114 hci_cc_reset(hdev, skb);
2115 break;
2116
2117 case HCI_OP_WRITE_LOCAL_NAME:
2118 hci_cc_write_local_name(hdev, skb);
2119 break;
2120
2121 case HCI_OP_READ_LOCAL_NAME:
2122 hci_cc_read_local_name(hdev, skb);
2123 break;
2124
2125 case HCI_OP_WRITE_AUTH_ENABLE:
2126 hci_cc_write_auth_enable(hdev, skb);
2127 break;
2128
2129 case HCI_OP_WRITE_ENCRYPT_MODE:
2130 hci_cc_write_encrypt_mode(hdev, skb);
2131 break;
2132
2133 case HCI_OP_WRITE_SCAN_ENABLE:
2134 hci_cc_write_scan_enable(hdev, skb);
2135 break;
2136
2137 case HCI_OP_READ_CLASS_OF_DEV:
2138 hci_cc_read_class_of_dev(hdev, skb);
2139 break;
2140
2141 case HCI_OP_WRITE_CLASS_OF_DEV:
2142 hci_cc_write_class_of_dev(hdev, skb);
2143 break;
2144
2145 case HCI_OP_READ_VOICE_SETTING:
2146 hci_cc_read_voice_setting(hdev, skb);
2147 break;
2148
2149 case HCI_OP_WRITE_VOICE_SETTING:
2150 hci_cc_write_voice_setting(hdev, skb);
2151 break;
2152
Marcel Holtmann333140b2008-07-14 20:13:48 +02002153 case HCI_OP_WRITE_SSP_MODE:
2154 hci_cc_write_ssp_mode(hdev, skb);
2155 break;
2156
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002157 case HCI_OP_READ_LOCAL_VERSION:
2158 hci_cc_read_local_version(hdev, skb);
2159 break;
2160
2161 case HCI_OP_READ_LOCAL_COMMANDS:
2162 hci_cc_read_local_commands(hdev, skb);
2163 break;
2164
2165 case HCI_OP_READ_LOCAL_FEATURES:
2166 hci_cc_read_local_features(hdev, skb);
2167 break;
2168
Andre Guedes971e3a42011-06-30 19:20:52 -03002169 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2170 hci_cc_read_local_ext_features(hdev, skb);
2171 break;
2172
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002173 case HCI_OP_READ_BUFFER_SIZE:
2174 hci_cc_read_buffer_size(hdev, skb);
2175 break;
2176
2177 case HCI_OP_READ_BD_ADDR:
2178 hci_cc_read_bd_addr(hdev, skb);
2179 break;
2180
Johan Hedbergf332ec62013-03-15 17:07:11 -05002181 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2182 hci_cc_read_page_scan_activity(hdev, skb);
2183 break;
2184
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002185 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2186 hci_cc_write_page_scan_activity(hdev, skb);
2187 break;
2188
Johan Hedbergf332ec62013-03-15 17:07:11 -05002189 case HCI_OP_READ_PAGE_SCAN_TYPE:
2190 hci_cc_read_page_scan_type(hdev, skb);
2191 break;
2192
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002193 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2194 hci_cc_write_page_scan_type(hdev, skb);
2195 break;
2196
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002197 case HCI_OP_READ_DATA_BLOCK_SIZE:
2198 hci_cc_read_data_block_size(hdev, skb);
2199 break;
2200
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002201 case HCI_OP_READ_FLOW_CONTROL_MODE:
2202 hci_cc_read_flow_control_mode(hdev, skb);
2203 break;
2204
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002205 case HCI_OP_READ_LOCAL_AMP_INFO:
2206 hci_cc_read_local_amp_info(hdev, skb);
2207 break;
2208
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002209 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2210 hci_cc_read_local_amp_assoc(hdev, skb);
2211 break;
2212
Johan Hedbergd5859e22011-01-25 01:19:58 +02002213 case HCI_OP_READ_INQ_RSP_TX_POWER:
2214 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2215 break;
2216
Johan Hedberg980e1a52011-01-22 06:10:07 +02002217 case HCI_OP_PIN_CODE_REPLY:
2218 hci_cc_pin_code_reply(hdev, skb);
2219 break;
2220
2221 case HCI_OP_PIN_CODE_NEG_REPLY:
2222 hci_cc_pin_code_neg_reply(hdev, skb);
2223 break;
2224
Szymon Jancc35938b2011-03-22 13:12:21 +01002225 case HCI_OP_READ_LOCAL_OOB_DATA:
2226 hci_cc_read_local_oob_data_reply(hdev, skb);
2227 break;
2228
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002229 case HCI_OP_LE_READ_BUFFER_SIZE:
2230 hci_cc_le_read_buffer_size(hdev, skb);
2231 break;
2232
Johan Hedberg60e77322013-01-22 14:01:59 +02002233 case HCI_OP_LE_READ_LOCAL_FEATURES:
2234 hci_cc_le_read_local_features(hdev, skb);
2235 break;
2236
Johan Hedberg8fa19092012-10-19 20:57:49 +03002237 case HCI_OP_LE_READ_ADV_TX_POWER:
2238 hci_cc_le_read_adv_tx_power(hdev, skb);
2239 break;
2240
Johan Hedberga5c29682011-02-19 12:05:57 -03002241 case HCI_OP_USER_CONFIRM_REPLY:
2242 hci_cc_user_confirm_reply(hdev, skb);
2243 break;
2244
2245 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2246 hci_cc_user_confirm_neg_reply(hdev, skb);
2247 break;
2248
Brian Gix1143d452011-11-23 08:28:34 -08002249 case HCI_OP_USER_PASSKEY_REPLY:
2250 hci_cc_user_passkey_reply(hdev, skb);
2251 break;
2252
2253 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2254 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002255 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002256
2257 case HCI_OP_LE_SET_SCAN_PARAM:
2258 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002259 break;
2260
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002261 case HCI_OP_LE_SET_ADV_ENABLE:
2262 hci_cc_le_set_adv_enable(hdev, skb);
2263 break;
2264
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002265 case HCI_OP_LE_SET_SCAN_ENABLE:
2266 hci_cc_le_set_scan_enable(hdev, skb);
2267 break;
2268
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002269 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2270 hci_cc_le_read_white_list_size(hdev, skb);
2271 break;
2272
Johan Hedberg9b008c02013-01-22 14:02:01 +02002273 case HCI_OP_LE_READ_SUPPORTED_STATES:
2274 hci_cc_le_read_supported_states(hdev, skb);
2275 break;
2276
Andre Guedesf9b49302011-06-30 19:20:53 -03002277 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2278 hci_cc_write_le_host_supported(hdev, skb);
2279 break;
2280
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002281 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2282 hci_cc_write_remote_amp_assoc(hdev, skb);
2283 break;
2284
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002285 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002286 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002287 break;
2288 }
2289
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002290 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002291 del_timer(&hdev->cmd_timer);
2292
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002293 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002294
Szymon Jancdbccd792012-12-11 08:51:19 +01002295 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002296 atomic_set(&hdev->cmd_cnt, 1);
2297 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002298 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002299 }
2300}
2301
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002302static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002303{
2304 struct hci_ev_cmd_status *ev = (void *) skb->data;
2305 __u16 opcode;
2306
2307 skb_pull(skb, sizeof(*ev));
2308
2309 opcode = __le16_to_cpu(ev->opcode);
2310
2311 switch (opcode) {
2312 case HCI_OP_INQUIRY:
2313 hci_cs_inquiry(hdev, ev->status);
2314 break;
2315
2316 case HCI_OP_CREATE_CONN:
2317 hci_cs_create_conn(hdev, ev->status);
2318 break;
2319
2320 case HCI_OP_ADD_SCO:
2321 hci_cs_add_sco(hdev, ev->status);
2322 break;
2323
Marcel Holtmannf8558552008-07-14 20:13:49 +02002324 case HCI_OP_AUTH_REQUESTED:
2325 hci_cs_auth_requested(hdev, ev->status);
2326 break;
2327
2328 case HCI_OP_SET_CONN_ENCRYPT:
2329 hci_cs_set_conn_encrypt(hdev, ev->status);
2330 break;
2331
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002332 case HCI_OP_REMOTE_NAME_REQ:
2333 hci_cs_remote_name_req(hdev, ev->status);
2334 break;
2335
Marcel Holtmann769be972008-07-14 20:13:49 +02002336 case HCI_OP_READ_REMOTE_FEATURES:
2337 hci_cs_read_remote_features(hdev, ev->status);
2338 break;
2339
2340 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2341 hci_cs_read_remote_ext_features(hdev, ev->status);
2342 break;
2343
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002344 case HCI_OP_SETUP_SYNC_CONN:
2345 hci_cs_setup_sync_conn(hdev, ev->status);
2346 break;
2347
2348 case HCI_OP_SNIFF_MODE:
2349 hci_cs_sniff_mode(hdev, ev->status);
2350 break;
2351
2352 case HCI_OP_EXIT_SNIFF_MODE:
2353 hci_cs_exit_sniff_mode(hdev, ev->status);
2354 break;
2355
Johan Hedberg8962ee72011-01-20 12:40:27 +02002356 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002357 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002358 break;
2359
Ville Tervofcd89c02011-02-10 22:38:47 -03002360 case HCI_OP_LE_CREATE_CONN:
2361 hci_cs_le_create_conn(hdev, ev->status);
2362 break;
2363
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002364 case HCI_OP_CREATE_PHY_LINK:
2365 hci_cs_create_phylink(hdev, ev->status);
2366 break;
2367
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002368 case HCI_OP_ACCEPT_PHY_LINK:
2369 hci_cs_accept_phylink(hdev, ev->status);
2370 break;
2371
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002372 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002373 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002374 break;
2375 }
2376
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002377 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002378 del_timer(&hdev->cmd_timer);
2379
Johan Hedberg02350a72013-04-03 21:50:29 +03002380 if (ev->status ||
2381 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2382 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002383
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002384 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002385 atomic_set(&hdev->cmd_cnt, 1);
2386 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002387 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002388 }
2389}
2390
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002391static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002392{
2393 struct hci_ev_role_change *ev = (void *) skb->data;
2394 struct hci_conn *conn;
2395
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002396 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002397
2398 hci_dev_lock(hdev);
2399
2400 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2401 if (conn) {
2402 if (!ev->status) {
2403 if (ev->role)
2404 conn->link_mode &= ~HCI_LM_MASTER;
2405 else
2406 conn->link_mode |= HCI_LM_MASTER;
2407 }
2408
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002409 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002410
2411 hci_role_switch_cfm(conn, ev->status, ev->role);
2412 }
2413
2414 hci_dev_unlock(hdev);
2415}
2416
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002417static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002419 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002420 int i;
2421
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002422 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2423 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2424 return;
2425 }
2426
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002427 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002428 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002429 BT_DBG("%s bad parameters", hdev->name);
2430 return;
2431 }
2432
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002433 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2434
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002435 for (i = 0; i < ev->num_hndl; i++) {
2436 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437 struct hci_conn *conn;
2438 __u16 handle, count;
2439
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002440 handle = __le16_to_cpu(info->handle);
2441 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442
2443 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002444 if (!conn)
2445 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002447 conn->sent -= count;
2448
2449 switch (conn->type) {
2450 case ACL_LINK:
2451 hdev->acl_cnt += count;
2452 if (hdev->acl_cnt > hdev->acl_pkts)
2453 hdev->acl_cnt = hdev->acl_pkts;
2454 break;
2455
2456 case LE_LINK:
2457 if (hdev->le_pkts) {
2458 hdev->le_cnt += count;
2459 if (hdev->le_cnt > hdev->le_pkts)
2460 hdev->le_cnt = hdev->le_pkts;
2461 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002462 hdev->acl_cnt += count;
2463 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002464 hdev->acl_cnt = hdev->acl_pkts;
2465 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002466 break;
2467
2468 case SCO_LINK:
2469 hdev->sco_cnt += count;
2470 if (hdev->sco_cnt > hdev->sco_pkts)
2471 hdev->sco_cnt = hdev->sco_pkts;
2472 break;
2473
2474 default:
2475 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2476 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002477 }
2478 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002479
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002480 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002481}
2482
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002483static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2484 __u16 handle)
2485{
2486 struct hci_chan *chan;
2487
2488 switch (hdev->dev_type) {
2489 case HCI_BREDR:
2490 return hci_conn_hash_lookup_handle(hdev, handle);
2491 case HCI_AMP:
2492 chan = hci_chan_lookup_handle(hdev, handle);
2493 if (chan)
2494 return chan->conn;
2495 break;
2496 default:
2497 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2498 break;
2499 }
2500
2501 return NULL;
2502}
2503
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002504static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002505{
2506 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2507 int i;
2508
2509 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2510 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2511 return;
2512 }
2513
2514 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002515 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002516 BT_DBG("%s bad parameters", hdev->name);
2517 return;
2518 }
2519
2520 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002521 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002522
2523 for (i = 0; i < ev->num_hndl; i++) {
2524 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002525 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002526 __u16 handle, block_count;
2527
2528 handle = __le16_to_cpu(info->handle);
2529 block_count = __le16_to_cpu(info->blocks);
2530
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002531 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002532 if (!conn)
2533 continue;
2534
2535 conn->sent -= block_count;
2536
2537 switch (conn->type) {
2538 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002539 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002540 hdev->block_cnt += block_count;
2541 if (hdev->block_cnt > hdev->num_blocks)
2542 hdev->block_cnt = hdev->num_blocks;
2543 break;
2544
2545 default:
2546 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2547 break;
2548 }
2549 }
2550
2551 queue_work(hdev->workqueue, &hdev->tx_work);
2552}
2553
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002554static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002556 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002557 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002559 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560
2561 hci_dev_lock(hdev);
2562
Marcel Holtmann04837f62006-07-03 10:02:33 +02002563 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2564 if (conn) {
2565 conn->mode = ev->mode;
2566 conn->interval = __le16_to_cpu(ev->interval);
2567
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002568 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2569 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002570 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002571 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002572 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002573 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002574 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002575
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002576 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002577 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002578 }
2579
2580 hci_dev_unlock(hdev);
2581}
2582
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002583static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002584{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002585 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2586 struct hci_conn *conn;
2587
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002588 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002589
2590 hci_dev_lock(hdev);
2591
2592 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002593 if (!conn)
2594 goto unlock;
2595
2596 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002597 hci_conn_hold(conn);
2598 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002599 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002600 }
2601
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002602 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002603 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002604 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002605 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002606 u8 secure;
2607
2608 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2609 secure = 1;
2610 else
2611 secure = 0;
2612
Johan Hedberg744cf192011-11-08 20:40:14 +02002613 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002614 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002615
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002616unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002617 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002618}
2619
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002620static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002621{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002622 struct hci_ev_link_key_req *ev = (void *) skb->data;
2623 struct hci_cp_link_key_reply cp;
2624 struct hci_conn *conn;
2625 struct link_key *key;
2626
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002627 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002628
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002629 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002630 return;
2631
2632 hci_dev_lock(hdev);
2633
2634 key = hci_find_link_key(hdev, &ev->bdaddr);
2635 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002636 BT_DBG("%s link key not found for %pMR", hdev->name,
2637 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002638 goto not_found;
2639 }
2640
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002641 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2642 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002643
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002644 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002645 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002646 BT_DBG("%s ignoring debug key", hdev->name);
2647 goto not_found;
2648 }
2649
2650 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002651 if (conn) {
2652 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002653 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002654 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2655 goto not_found;
2656 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002657
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002658 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002659 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002660 BT_DBG("%s ignoring key unauthenticated for high security",
2661 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002662 goto not_found;
2663 }
2664
2665 conn->key_type = key->type;
2666 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002667 }
2668
2669 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002670 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002671
2672 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2673
2674 hci_dev_unlock(hdev);
2675
2676 return;
2677
2678not_found:
2679 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2680 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002681}
2682
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002683static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002684{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002685 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2686 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002687 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002688
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002689 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002690
2691 hci_dev_lock(hdev);
2692
2693 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2694 if (conn) {
2695 hci_conn_hold(conn);
2696 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002697 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002698
2699 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2700 conn->key_type = ev->key_type;
2701
David Herrmann76a68ba2013-04-06 20:28:37 +02002702 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002703 }
2704
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002705 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002706 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002707 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002708
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002709 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710}
2711
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002712static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002713{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002714 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002715 struct hci_conn *conn;
2716
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002717 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002718
2719 hci_dev_lock(hdev);
2720
2721 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002722 if (conn && !ev->status) {
2723 struct inquiry_entry *ie;
2724
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002725 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2726 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727 ie->data.clock_offset = ev->clock_offset;
2728 ie->timestamp = jiffies;
2729 }
2730 }
2731
2732 hci_dev_unlock(hdev);
2733}
2734
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002735static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002736{
2737 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2738 struct hci_conn *conn;
2739
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002740 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002741
2742 hci_dev_lock(hdev);
2743
2744 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2745 if (conn && !ev->status)
2746 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2747
2748 hci_dev_unlock(hdev);
2749}
2750
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002751static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002752{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002753 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002754 struct inquiry_entry *ie;
2755
2756 BT_DBG("%s", hdev->name);
2757
2758 hci_dev_lock(hdev);
2759
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002760 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2761 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002762 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2763 ie->timestamp = jiffies;
2764 }
2765
2766 hci_dev_unlock(hdev);
2767}
2768
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002769static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2770 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002771{
2772 struct inquiry_data data;
2773 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002774 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002775
2776 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2777
2778 if (!num_rsp)
2779 return;
2780
Andre Guedes1519cc12012-03-21 00:03:38 -03002781 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2782 return;
2783
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002784 hci_dev_lock(hdev);
2785
2786 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002787 struct inquiry_info_with_rssi_and_pscan_mode *info;
2788 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002789
Johan Hedberge17acd42011-03-30 23:57:16 +03002790 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002791 bacpy(&data.bdaddr, &info->bdaddr);
2792 data.pscan_rep_mode = info->pscan_rep_mode;
2793 data.pscan_period_mode = info->pscan_period_mode;
2794 data.pscan_mode = info->pscan_mode;
2795 memcpy(data.dev_class, info->dev_class, 3);
2796 data.clock_offset = info->clock_offset;
2797 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002798 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002799
2800 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002801 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002802 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002803 info->dev_class, info->rssi,
2804 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002805 }
2806 } else {
2807 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2808
Johan Hedberge17acd42011-03-30 23:57:16 +03002809 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002810 bacpy(&data.bdaddr, &info->bdaddr);
2811 data.pscan_rep_mode = info->pscan_rep_mode;
2812 data.pscan_period_mode = info->pscan_period_mode;
2813 data.pscan_mode = 0x00;
2814 memcpy(data.dev_class, info->dev_class, 3);
2815 data.clock_offset = info->clock_offset;
2816 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002817 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002818 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002819 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002820 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002821 info->dev_class, info->rssi,
2822 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002823 }
2824 }
2825
2826 hci_dev_unlock(hdev);
2827}
2828
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002829static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2830 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002831{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002832 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2833 struct hci_conn *conn;
2834
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002835 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002836
Marcel Holtmann41a96212008-07-14 20:13:48 +02002837 hci_dev_lock(hdev);
2838
2839 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002840 if (!conn)
2841 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002842
Johan Hedbergcad718e2013-04-17 15:00:51 +03002843 if (ev->page < HCI_MAX_PAGES)
2844 memcpy(conn->features[ev->page], ev->features, 8);
2845
Johan Hedbergccd556f2010-11-10 17:11:51 +02002846 if (!ev->status && ev->page == 0x01) {
2847 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002848
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002849 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2850 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002851 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002852
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302853 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002854 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302855 } else {
2856 /* It is mandatory by the Bluetooth specification that
2857 * Extended Inquiry Results are only used when Secure
2858 * Simple Pairing is enabled, but some devices violate
2859 * this.
2860 *
2861 * To make these devices work, the internal SSP
2862 * enabled flag needs to be cleared if the remote host
2863 * features do not indicate SSP support */
2864 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2865 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002866 }
2867
Johan Hedbergccd556f2010-11-10 17:11:51 +02002868 if (conn->state != BT_CONFIG)
2869 goto unlock;
2870
Johan Hedberg671267b2012-05-12 16:11:50 -03002871 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002872 struct hci_cp_remote_name_req cp;
2873 memset(&cp, 0, sizeof(cp));
2874 bacpy(&cp.bdaddr, &conn->dst);
2875 cp.pscan_rep_mode = 0x02;
2876 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002877 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2878 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002879 conn->dst_type, 0, NULL, 0,
2880 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002881
Johan Hedberg127178d2010-11-18 22:22:29 +02002882 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002883 conn->state = BT_CONNECTED;
2884 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002885 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002886 }
2887
2888unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002889 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002890}
2891
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002892static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2893 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002894{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002895 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2896 struct hci_conn *conn;
2897
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002898 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002899
2900 hci_dev_lock(hdev);
2901
2902 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002903 if (!conn) {
2904 if (ev->link_type == ESCO_LINK)
2905 goto unlock;
2906
2907 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2908 if (!conn)
2909 goto unlock;
2910
2911 conn->type = SCO_LINK;
2912 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002913
Marcel Holtmann732547f2009-04-19 19:14:14 +02002914 switch (ev->status) {
2915 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002916 conn->handle = __le16_to_cpu(ev->handle);
2917 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002918
2919 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002920 break;
2921
Stephen Coe705e5712010-02-16 11:29:44 -05002922 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002923 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002924 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002925 case 0x1f: /* Unspecified error */
2926 if (conn->out && conn->attempt < 2) {
2927 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2928 (hdev->esco_type & EDR_ESCO_MASK);
2929 hci_setup_sync(conn, conn->link->handle);
2930 goto unlock;
2931 }
2932 /* fall through */
2933
2934 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002935 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002936 break;
2937 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002938
2939 hci_proto_connect_cfm(conn, ev->status);
2940 if (ev->status)
2941 hci_conn_del(conn);
2942
2943unlock:
2944 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002945}
2946
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002947static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2948 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002949{
2950 struct inquiry_data data;
2951 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2952 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302953 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002954
2955 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2956
2957 if (!num_rsp)
2958 return;
2959
Andre Guedes1519cc12012-03-21 00:03:38 -03002960 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2961 return;
2962
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002963 hci_dev_lock(hdev);
2964
Johan Hedberge17acd42011-03-30 23:57:16 +03002965 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002966 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002967
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002968 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002969 data.pscan_rep_mode = info->pscan_rep_mode;
2970 data.pscan_period_mode = info->pscan_period_mode;
2971 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002972 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002973 data.clock_offset = info->clock_offset;
2974 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002975 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002976
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002977 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002978 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002979 sizeof(info->data),
2980 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002981 else
2982 name_known = true;
2983
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002984 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002985 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302986 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02002987 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002988 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302989 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002990 }
2991
2992 hci_dev_unlock(hdev);
2993}
2994
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002995static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
2996 struct sk_buff *skb)
2997{
2998 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
2999 struct hci_conn *conn;
3000
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003001 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003002 __le16_to_cpu(ev->handle));
3003
3004 hci_dev_lock(hdev);
3005
3006 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3007 if (!conn)
3008 goto unlock;
3009
3010 if (!ev->status)
3011 conn->sec_level = conn->pending_sec_level;
3012
3013 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3014
3015 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003016 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003017 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003018 goto unlock;
3019 }
3020
3021 if (conn->state == BT_CONFIG) {
3022 if (!ev->status)
3023 conn->state = BT_CONNECTED;
3024
3025 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003026 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003027 } else {
3028 hci_auth_cfm(conn, ev->status);
3029
3030 hci_conn_hold(conn);
3031 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003032 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003033 }
3034
3035unlock:
3036 hci_dev_unlock(hdev);
3037}
3038
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003039static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003040{
3041 /* If remote requests dedicated bonding follow that lead */
3042 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3043 /* If both remote and local IO capabilities allow MITM
3044 * protection then require it, otherwise don't */
3045 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3046 return 0x02;
3047 else
3048 return 0x03;
3049 }
3050
3051 /* If remote requests no-bonding follow that lead */
3052 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003053 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003054
3055 return conn->auth_type;
3056}
3057
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003058static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003059{
3060 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3061 struct hci_conn *conn;
3062
3063 BT_DBG("%s", hdev->name);
3064
3065 hci_dev_lock(hdev);
3066
3067 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003068 if (!conn)
3069 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003070
Johan Hedberg03b555e2011-01-04 15:40:05 +02003071 hci_conn_hold(conn);
3072
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003073 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003074 goto unlock;
3075
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003076 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003077 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003078 struct hci_cp_io_capability_reply cp;
3079
3080 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303081 /* Change the IO capability from KeyboardDisplay
3082 * to DisplayYesNo as it is not supported by BT spec. */
3083 cp.capability = (conn->io_capability == 0x04) ?
3084 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003085 conn->auth_type = hci_get_auth_req(conn);
3086 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003087
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003088 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3089 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003090 cp.oob_data = 0x01;
3091 else
3092 cp.oob_data = 0x00;
3093
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003094 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003095 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003096 } else {
3097 struct hci_cp_io_capability_neg_reply cp;
3098
3099 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003100 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003101
3102 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003103 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003104 }
3105
3106unlock:
3107 hci_dev_unlock(hdev);
3108}
3109
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003110static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003111{
3112 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3113 struct hci_conn *conn;
3114
3115 BT_DBG("%s", hdev->name);
3116
3117 hci_dev_lock(hdev);
3118
3119 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3120 if (!conn)
3121 goto unlock;
3122
Johan Hedberg03b555e2011-01-04 15:40:05 +02003123 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003124 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003125 if (ev->oob_data)
3126 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003127
3128unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003129 hci_dev_unlock(hdev);
3130}
3131
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003132static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3133 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003134{
3135 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003136 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003137 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003138
3139 BT_DBG("%s", hdev->name);
3140
3141 hci_dev_lock(hdev);
3142
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003143 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003144 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003145
Johan Hedberg7a828902011-04-28 11:28:53 -07003146 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3147 if (!conn)
3148 goto unlock;
3149
3150 loc_mitm = (conn->auth_type & 0x01);
3151 rem_mitm = (conn->remote_auth & 0x01);
3152
3153 /* If we require MITM but the remote device can't provide that
3154 * (it has NoInputNoOutput) then reject the confirmation
3155 * request. The only exception is when we're dedicated bonding
3156 * initiators (connect_cfm_cb set) since then we always have the MITM
3157 * bit set. */
3158 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3159 BT_DBG("Rejecting request: remote device can't provide MITM");
3160 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003161 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003162 goto unlock;
3163 }
3164
3165 /* If no side requires MITM protection; auto-accept */
3166 if ((!loc_mitm || conn->remote_cap == 0x03) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003167 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003168
3169 /* If we're not the initiators request authorization to
3170 * proceed from user space (mgmt_user_confirm with
3171 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003172 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003173 BT_DBG("Confirming auto-accept as acceptor");
3174 confirm_hint = 1;
3175 goto confirm;
3176 }
3177
Johan Hedberg9f616562011-04-28 11:28:54 -07003178 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003179 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003180
3181 if (hdev->auto_accept_delay > 0) {
3182 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3183 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3184 goto unlock;
3185 }
3186
Johan Hedberg7a828902011-04-28 11:28:53 -07003187 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003188 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003189 goto unlock;
3190 }
3191
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003192confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003193 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003194 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003195
3196unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003197 hci_dev_unlock(hdev);
3198}
3199
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003200static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3201 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003202{
3203 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3204
3205 BT_DBG("%s", hdev->name);
3206
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003207 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003208 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003209}
3210
Johan Hedberg92a25252012-09-06 18:39:26 +03003211static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3212 struct sk_buff *skb)
3213{
3214 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3215 struct hci_conn *conn;
3216
3217 BT_DBG("%s", hdev->name);
3218
3219 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3220 if (!conn)
3221 return;
3222
3223 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3224 conn->passkey_entered = 0;
3225
3226 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3227 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3228 conn->dst_type, conn->passkey_notify,
3229 conn->passkey_entered);
3230}
3231
3232static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3233{
3234 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3235 struct hci_conn *conn;
3236
3237 BT_DBG("%s", hdev->name);
3238
3239 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3240 if (!conn)
3241 return;
3242
3243 switch (ev->type) {
3244 case HCI_KEYPRESS_STARTED:
3245 conn->passkey_entered = 0;
3246 return;
3247
3248 case HCI_KEYPRESS_ENTERED:
3249 conn->passkey_entered++;
3250 break;
3251
3252 case HCI_KEYPRESS_ERASED:
3253 conn->passkey_entered--;
3254 break;
3255
3256 case HCI_KEYPRESS_CLEARED:
3257 conn->passkey_entered = 0;
3258 break;
3259
3260 case HCI_KEYPRESS_COMPLETED:
3261 return;
3262 }
3263
3264 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3265 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3266 conn->dst_type, conn->passkey_notify,
3267 conn->passkey_entered);
3268}
3269
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003270static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3271 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003272{
3273 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3274 struct hci_conn *conn;
3275
3276 BT_DBG("%s", hdev->name);
3277
3278 hci_dev_lock(hdev);
3279
3280 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003281 if (!conn)
3282 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003283
Johan Hedberg2a611692011-02-19 12:06:00 -03003284 /* To avoid duplicate auth_failed events to user space we check
3285 * the HCI_CONN_AUTH_PEND flag which will be set if we
3286 * initiated the authentication. A traditional auth_complete
3287 * event gets always produced as initiator and is also mapped to
3288 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003289 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003290 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003291 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003292
David Herrmann76a68ba2013-04-06 20:28:37 +02003293 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003294
3295unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003296 hci_dev_unlock(hdev);
3297}
3298
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003299static void hci_remote_host_features_evt(struct hci_dev *hdev,
3300 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003301{
3302 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3303 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003304 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003305
3306 BT_DBG("%s", hdev->name);
3307
3308 hci_dev_lock(hdev);
3309
Johan Hedbergcad718e2013-04-17 15:00:51 +03003310 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3311 if (conn)
3312 memcpy(conn->features[1], ev->features, 8);
3313
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003314 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3315 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003316 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003317
3318 hci_dev_unlock(hdev);
3319}
3320
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003321static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3322 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003323{
3324 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3325 struct oob_data *data;
3326
3327 BT_DBG("%s", hdev->name);
3328
3329 hci_dev_lock(hdev);
3330
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003331 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003332 goto unlock;
3333
Szymon Janc2763eda2011-03-22 13:12:22 +01003334 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3335 if (data) {
3336 struct hci_cp_remote_oob_data_reply cp;
3337
3338 bacpy(&cp.bdaddr, &ev->bdaddr);
3339 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3340 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3341
3342 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003343 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003344 } else {
3345 struct hci_cp_remote_oob_data_neg_reply cp;
3346
3347 bacpy(&cp.bdaddr, &ev->bdaddr);
3348 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003349 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003350 }
3351
Szymon Jance1ba1f12011-04-06 13:01:59 +02003352unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003353 hci_dev_unlock(hdev);
3354}
3355
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003356static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3357 struct sk_buff *skb)
3358{
3359 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3360 struct hci_conn *hcon, *bredr_hcon;
3361
3362 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3363 ev->status);
3364
3365 hci_dev_lock(hdev);
3366
3367 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3368 if (!hcon) {
3369 hci_dev_unlock(hdev);
3370 return;
3371 }
3372
3373 if (ev->status) {
3374 hci_conn_del(hcon);
3375 hci_dev_unlock(hdev);
3376 return;
3377 }
3378
3379 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3380
3381 hcon->state = BT_CONNECTED;
3382 bacpy(&hcon->dst, &bredr_hcon->dst);
3383
3384 hci_conn_hold(hcon);
3385 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003386 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003387
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003388 hci_conn_add_sysfs(hcon);
3389
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003390 amp_physical_cfm(bredr_hcon, hcon);
3391
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003392 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003393}
3394
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003395static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3396{
3397 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3398 struct hci_conn *hcon;
3399 struct hci_chan *hchan;
3400 struct amp_mgr *mgr;
3401
3402 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3403 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3404 ev->status);
3405
3406 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3407 if (!hcon)
3408 return;
3409
3410 /* Create AMP hchan */
3411 hchan = hci_chan_create(hcon);
3412 if (!hchan)
3413 return;
3414
3415 hchan->handle = le16_to_cpu(ev->handle);
3416
3417 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3418
3419 mgr = hcon->amp_mgr;
3420 if (mgr && mgr->bredr_chan) {
3421 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3422
3423 l2cap_chan_lock(bredr_chan);
3424
3425 bredr_chan->conn->mtu = hdev->block_mtu;
3426 l2cap_logical_cfm(bredr_chan, hchan, 0);
3427 hci_conn_hold(hcon);
3428
3429 l2cap_chan_unlock(bredr_chan);
3430 }
3431}
3432
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003433static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3434 struct sk_buff *skb)
3435{
3436 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3437 struct hci_chan *hchan;
3438
3439 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3440 le16_to_cpu(ev->handle), ev->status);
3441
3442 if (ev->status)
3443 return;
3444
3445 hci_dev_lock(hdev);
3446
3447 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3448 if (!hchan)
3449 goto unlock;
3450
3451 amp_destroy_logical_link(hchan, ev->reason);
3452
3453unlock:
3454 hci_dev_unlock(hdev);
3455}
3456
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003457static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3458 struct sk_buff *skb)
3459{
3460 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3461 struct hci_conn *hcon;
3462
3463 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3464
3465 if (ev->status)
3466 return;
3467
3468 hci_dev_lock(hdev);
3469
3470 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3471 if (hcon) {
3472 hcon->state = BT_CLOSED;
3473 hci_conn_del(hcon);
3474 }
3475
3476 hci_dev_unlock(hdev);
3477}
3478
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003479static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003480{
3481 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3482 struct hci_conn *conn;
3483
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003484 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003485
3486 hci_dev_lock(hdev);
3487
Andre Guedesb47a09b2012-07-27 15:10:15 -03003488 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003489 if (!conn) {
3490 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3491 if (!conn) {
3492 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003493 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003494 }
Andre Guedes29b79882011-05-31 14:20:54 -03003495
3496 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003497
3498 if (ev->role == LE_CONN_ROLE_MASTER) {
3499 conn->out = true;
3500 conn->link_mode |= HCI_LM_MASTER;
3501 }
Ville Tervob62f3282011-02-10 22:38:50 -03003502 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003503
Andre Guedescd17dec2012-07-27 15:10:16 -03003504 if (ev->status) {
3505 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3506 conn->dst_type, ev->status);
3507 hci_proto_connect_cfm(conn, ev->status);
3508 conn->state = BT_CLOSED;
3509 hci_conn_del(conn);
3510 goto unlock;
3511 }
3512
Johan Hedbergb644ba32012-01-17 21:48:47 +02003513 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3514 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003515 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003516
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003517 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003518 conn->handle = __le16_to_cpu(ev->handle);
3519 conn->state = BT_CONNECTED;
3520
Ville Tervofcd89c02011-02-10 22:38:47 -03003521 hci_conn_add_sysfs(conn);
3522
3523 hci_proto_connect_cfm(conn, ev->status);
3524
3525unlock:
3526 hci_dev_unlock(hdev);
3527}
3528
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003529static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003530{
Andre Guedese95beb42011-09-26 20:48:35 -03003531 u8 num_reports = skb->data[0];
3532 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003533 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003534
Andre Guedese95beb42011-09-26 20:48:35 -03003535 while (num_reports--) {
3536 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003537
Andre Guedes3c9e9192012-01-10 18:20:50 -03003538 rssi = ev->data[ev->length];
3539 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003540 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003541
Andre Guedese95beb42011-09-26 20:48:35 -03003542 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003543 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003544}
3545
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003546static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003547{
3548 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3549 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003550 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003551 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003552 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003553
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003554 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003555
3556 hci_dev_lock(hdev);
3557
3558 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003559 if (conn == NULL)
3560 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003561
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003562 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3563 if (ltk == NULL)
3564 goto not_found;
3565
3566 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003567 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003568
3569 if (ltk->authenticated)
3570 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003571
3572 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3573
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003574 if (ltk->type & HCI_SMP_STK) {
3575 list_del(&ltk->list);
3576 kfree(ltk);
3577 }
3578
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003579 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003580
3581 return;
3582
3583not_found:
3584 neg.handle = ev->handle;
3585 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3586 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003587}
3588
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003589static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003590{
3591 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3592
3593 skb_pull(skb, sizeof(*le_ev));
3594
3595 switch (le_ev->subevent) {
3596 case HCI_EV_LE_CONN_COMPLETE:
3597 hci_le_conn_complete_evt(hdev, skb);
3598 break;
3599
Andre Guedes9aa04c92011-05-26 16:23:51 -03003600 case HCI_EV_LE_ADVERTISING_REPORT:
3601 hci_le_adv_report_evt(hdev, skb);
3602 break;
3603
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003604 case HCI_EV_LE_LTK_REQ:
3605 hci_le_ltk_request_evt(hdev, skb);
3606 break;
3607
Ville Tervofcd89c02011-02-10 22:38:47 -03003608 default:
3609 break;
3610 }
3611}
3612
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003613static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3614{
3615 struct hci_ev_channel_selected *ev = (void *) skb->data;
3616 struct hci_conn *hcon;
3617
3618 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3619
3620 skb_pull(skb, sizeof(*ev));
3621
3622 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3623 if (!hcon)
3624 return;
3625
3626 amp_read_loc_assoc_final_data(hdev, hcon);
3627}
3628
Linus Torvalds1da177e2005-04-16 15:20:36 -07003629void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3630{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003631 struct hci_event_hdr *hdr = (void *) skb->data;
3632 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003633
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003634 hci_dev_lock(hdev);
3635
3636 /* Received events are (currently) only needed when a request is
3637 * ongoing so avoid unnecessary memory allocation.
3638 */
3639 if (hdev->req_status == HCI_REQ_PEND) {
3640 kfree_skb(hdev->recv_evt);
3641 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3642 }
3643
3644 hci_dev_unlock(hdev);
3645
Linus Torvalds1da177e2005-04-16 15:20:36 -07003646 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3647
Johan Hedberg02350a72013-04-03 21:50:29 +03003648 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
3649 struct hci_command_hdr *hdr = (void *) hdev->sent_cmd->data;
3650 u16 opcode = __le16_to_cpu(hdr->opcode);
3651
3652 hci_req_cmd_complete(hdev, opcode, 0);
3653 }
3654
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003655 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003656 case HCI_EV_INQUIRY_COMPLETE:
3657 hci_inquiry_complete_evt(hdev, skb);
3658 break;
3659
3660 case HCI_EV_INQUIRY_RESULT:
3661 hci_inquiry_result_evt(hdev, skb);
3662 break;
3663
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003664 case HCI_EV_CONN_COMPLETE:
3665 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003666 break;
3667
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668 case HCI_EV_CONN_REQUEST:
3669 hci_conn_request_evt(hdev, skb);
3670 break;
3671
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672 case HCI_EV_DISCONN_COMPLETE:
3673 hci_disconn_complete_evt(hdev, skb);
3674 break;
3675
Linus Torvalds1da177e2005-04-16 15:20:36 -07003676 case HCI_EV_AUTH_COMPLETE:
3677 hci_auth_complete_evt(hdev, skb);
3678 break;
3679
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003680 case HCI_EV_REMOTE_NAME:
3681 hci_remote_name_evt(hdev, skb);
3682 break;
3683
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684 case HCI_EV_ENCRYPT_CHANGE:
3685 hci_encrypt_change_evt(hdev, skb);
3686 break;
3687
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003688 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3689 hci_change_link_key_complete_evt(hdev, skb);
3690 break;
3691
3692 case HCI_EV_REMOTE_FEATURES:
3693 hci_remote_features_evt(hdev, skb);
3694 break;
3695
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003696 case HCI_EV_CMD_COMPLETE:
3697 hci_cmd_complete_evt(hdev, skb);
3698 break;
3699
3700 case HCI_EV_CMD_STATUS:
3701 hci_cmd_status_evt(hdev, skb);
3702 break;
3703
3704 case HCI_EV_ROLE_CHANGE:
3705 hci_role_change_evt(hdev, skb);
3706 break;
3707
3708 case HCI_EV_NUM_COMP_PKTS:
3709 hci_num_comp_pkts_evt(hdev, skb);
3710 break;
3711
3712 case HCI_EV_MODE_CHANGE:
3713 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003714 break;
3715
3716 case HCI_EV_PIN_CODE_REQ:
3717 hci_pin_code_request_evt(hdev, skb);
3718 break;
3719
3720 case HCI_EV_LINK_KEY_REQ:
3721 hci_link_key_request_evt(hdev, skb);
3722 break;
3723
3724 case HCI_EV_LINK_KEY_NOTIFY:
3725 hci_link_key_notify_evt(hdev, skb);
3726 break;
3727
3728 case HCI_EV_CLOCK_OFFSET:
3729 hci_clock_offset_evt(hdev, skb);
3730 break;
3731
Marcel Holtmanna8746412008-07-14 20:13:46 +02003732 case HCI_EV_PKT_TYPE_CHANGE:
3733 hci_pkt_type_change_evt(hdev, skb);
3734 break;
3735
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003736 case HCI_EV_PSCAN_REP_MODE:
3737 hci_pscan_rep_mode_evt(hdev, skb);
3738 break;
3739
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003740 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3741 hci_inquiry_result_with_rssi_evt(hdev, skb);
3742 break;
3743
3744 case HCI_EV_REMOTE_EXT_FEATURES:
3745 hci_remote_ext_features_evt(hdev, skb);
3746 break;
3747
3748 case HCI_EV_SYNC_CONN_COMPLETE:
3749 hci_sync_conn_complete_evt(hdev, skb);
3750 break;
3751
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003752 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3753 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754 break;
3755
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003756 case HCI_EV_KEY_REFRESH_COMPLETE:
3757 hci_key_refresh_complete_evt(hdev, skb);
3758 break;
3759
Marcel Holtmann04936842008-07-14 20:13:48 +02003760 case HCI_EV_IO_CAPA_REQUEST:
3761 hci_io_capa_request_evt(hdev, skb);
3762 break;
3763
Johan Hedberg03b555e2011-01-04 15:40:05 +02003764 case HCI_EV_IO_CAPA_REPLY:
3765 hci_io_capa_reply_evt(hdev, skb);
3766 break;
3767
Johan Hedberga5c29682011-02-19 12:05:57 -03003768 case HCI_EV_USER_CONFIRM_REQUEST:
3769 hci_user_confirm_request_evt(hdev, skb);
3770 break;
3771
Brian Gix1143d452011-11-23 08:28:34 -08003772 case HCI_EV_USER_PASSKEY_REQUEST:
3773 hci_user_passkey_request_evt(hdev, skb);
3774 break;
3775
Johan Hedberg92a25252012-09-06 18:39:26 +03003776 case HCI_EV_USER_PASSKEY_NOTIFY:
3777 hci_user_passkey_notify_evt(hdev, skb);
3778 break;
3779
3780 case HCI_EV_KEYPRESS_NOTIFY:
3781 hci_keypress_notify_evt(hdev, skb);
3782 break;
3783
Marcel Holtmann04936842008-07-14 20:13:48 +02003784 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3785 hci_simple_pair_complete_evt(hdev, skb);
3786 break;
3787
Marcel Holtmann41a96212008-07-14 20:13:48 +02003788 case HCI_EV_REMOTE_HOST_FEATURES:
3789 hci_remote_host_features_evt(hdev, skb);
3790 break;
3791
Ville Tervofcd89c02011-02-10 22:38:47 -03003792 case HCI_EV_LE_META:
3793 hci_le_meta_evt(hdev, skb);
3794 break;
3795
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003796 case HCI_EV_CHANNEL_SELECTED:
3797 hci_chan_selected_evt(hdev, skb);
3798 break;
3799
Szymon Janc2763eda2011-03-22 13:12:22 +01003800 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3801 hci_remote_oob_data_request_evt(hdev, skb);
3802 break;
3803
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003804 case HCI_EV_PHY_LINK_COMPLETE:
3805 hci_phy_link_complete_evt(hdev, skb);
3806 break;
3807
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003808 case HCI_EV_LOGICAL_LINK_COMPLETE:
3809 hci_loglink_complete_evt(hdev, skb);
3810 break;
3811
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003812 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3813 hci_disconn_loglink_complete_evt(hdev, skb);
3814 break;
3815
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003816 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3817 hci_disconn_phylink_complete_evt(hdev, skb);
3818 break;
3819
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003820 case HCI_EV_NUM_COMP_BLOCKS:
3821 hci_num_comp_blocks_evt(hdev, skb);
3822 break;
3823
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003824 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003825 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826 break;
3827 }
3828
3829 kfree_skb(skb);
3830 hdev->stat.evt_rx++;
3831}