blob: 2ecb34f2e2adad68cf7a874cce8ce8ac6dea7bfb [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>
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070032
Marcel Holtmann70247282013-10-10 14:54:15 -070033#include "a2mp.h"
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070034#include "amp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
Linus Torvalds1da177e2005-04-16 15:20:36 -070036/* Handle HCI Event packets */
37
Marcel Holtmanna9de9242007-10-20 13:33:56 +020038static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070039{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020040 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030042 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
Andre Guedes82f47852013-04-30 15:29:34 -030044 if (status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020045 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
Andre Guedes89352e72011-11-04 14:16:53 -030047 clear_bit(HCI_INQUIRY, &hdev->flags);
Andre Guedes3e13fa12013-03-27 20:04:56 -030048 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
49 wake_up_bit(&hdev->flags, HCI_INQUIRY);
Andre Guedes89352e72011-11-04 14:16:53 -030050
Marcel Holtmanna9de9242007-10-20 13:33:56 +020051 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052}
53
Andre Guedes4d934832012-03-21 00:03:35 -030054static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
55{
56 __u8 status = *((__u8 *) skb->data);
57
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030058 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030059
60 if (status)
61 return;
62
63 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030064}
65
Marcel Holtmanna9de9242007-10-20 13:33:56 +020066static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020068 __u8 status = *((__u8 *) skb->data);
69
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030070 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020071
72 if (status)
73 return;
74
Andre Guedesae854a72012-03-21 00:03:36 -030075 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
76
Marcel Holtmanna9de9242007-10-20 13:33:56 +020077 hci_conn_check_pending(hdev);
78}
79
Gustavo Padovan807deac2012-05-17 00:36:24 -030080static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
81 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020082{
83 BT_DBG("%s", hdev->name);
84}
85
86static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
87{
88 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030091 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
Marcel Holtmanna9de9242007-10-20 13:33:56 +020093 if (rp->status)
94 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
Marcel Holtmanna9de9242007-10-20 13:33:56 +020096 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Marcel Holtmanna9de9242007-10-20 13:33:56 +020098 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
99 if (conn) {
100 if (rp->role)
101 conn->link_mode &= ~HCI_LM_MASTER;
102 else
103 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105
106 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107}
108
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200109static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
110{
111 struct hci_rp_read_link_policy *rp = (void *) skb->data;
112 struct hci_conn *conn;
113
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300114 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200115
116 if (rp->status)
117 return;
118
119 hci_dev_lock(hdev);
120
121 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
122 if (conn)
123 conn->link_policy = __le16_to_cpu(rp->policy);
124
125 hci_dev_unlock(hdev);
126}
127
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200128static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200130 struct hci_rp_write_link_policy *rp = (void *) skb->data;
131 struct hci_conn *conn;
132 void *sent;
133
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300134 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135
136 if (rp->status)
137 return;
138
139 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
140 if (!sent)
141 return;
142
143 hci_dev_lock(hdev);
144
145 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200146 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700147 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200148
149 hci_dev_unlock(hdev);
150}
151
Gustavo Padovan807deac2012-05-17 00:36:24 -0300152static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
153 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200154{
155 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
156
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300157 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200158
159 if (rp->status)
160 return;
161
162 hdev->link_policy = __le16_to_cpu(rp->policy);
163}
164
Gustavo Padovan807deac2012-05-17 00:36:24 -0300165static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
166 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200167{
168 __u8 status = *((__u8 *) skb->data);
169 void *sent;
170
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300171 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200172
173 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
174 if (!sent)
175 return;
176
177 if (!status)
178 hdev->link_policy = get_unaligned_le16(sent);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200179}
180
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200181static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
182{
183 __u8 status = *((__u8 *) skb->data);
184
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300185 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200186
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300187 clear_bit(HCI_RESET, &hdev->flags);
188
Johan Hedberga297e972012-02-21 17:55:47 +0200189 /* Reset all non-persistent flags */
Johan Hedberg2cc6fb02013-03-15 17:06:57 -0500190 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
Andre Guedes69775ff2012-02-23 16:50:05 +0200191
192 hdev->discovery.state = DISCOVERY_STOPPED;
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100193 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
194 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100195
196 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
197 hdev->adv_data_len = 0;
Marcel Holtmannf8e808b2013-10-16 00:16:47 -0700198
199 memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
200 hdev->scan_rsp_data_len = 0;
Marcel Holtmann06f5b772013-10-19 07:09:11 -0700201
Marcel Holtmann533553f2014-03-21 12:18:10 -0700202 hdev->le_scan_type = LE_SCAN_PASSIVE;
203
Marcel Holtmann06f5b772013-10-19 07:09:11 -0700204 hdev->ssp_debug_mode = 0;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200205}
206
207static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
208{
209 __u8 status = *((__u8 *) skb->data);
210 void *sent;
211
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300212 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200213
214 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
215 if (!sent)
216 return;
217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 hci_dev_lock(hdev);
219
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200220 if (test_bit(HCI_MGMT, &hdev->dev_flags))
221 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200222 else if (!status)
223 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200224
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200225 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200226}
227
228static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
229{
230 struct hci_rp_read_local_name *rp = (void *) skb->data;
231
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300232 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200233
234 if (rp->status)
235 return;
236
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200237 if (test_bit(HCI_SETUP, &hdev->dev_flags))
238 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200239}
240
241static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
242{
243 __u8 status = *((__u8 *) skb->data);
244 void *sent;
245
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300246 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200247
248 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
249 if (!sent)
250 return;
251
252 if (!status) {
253 __u8 param = *((__u8 *) sent);
254
255 if (param == AUTH_ENABLED)
256 set_bit(HCI_AUTH, &hdev->flags);
257 else
258 clear_bit(HCI_AUTH, &hdev->flags);
259 }
260
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200261 if (test_bit(HCI_MGMT, &hdev->dev_flags))
262 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200263}
264
265static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
266{
267 __u8 status = *((__u8 *) skb->data);
268 void *sent;
269
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300270 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200271
272 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
273 if (!sent)
274 return;
275
276 if (!status) {
277 __u8 param = *((__u8 *) sent);
278
279 if (param)
280 set_bit(HCI_ENCRYPT, &hdev->flags);
281 else
282 clear_bit(HCI_ENCRYPT, &hdev->flags);
283 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200284}
285
286static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
287{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200288 __u8 param, status = *((__u8 *) skb->data);
289 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200290 void *sent;
291
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300292 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200293
294 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
295 if (!sent)
296 return;
297
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200298 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200299
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200300 hci_dev_lock(hdev);
301
Mikel Astizfa1bd912012-08-09 09:52:29 +0200302 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200303 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200304 hdev->discov_timeout = 0;
305 goto done;
306 }
307
Johan Hedberg0663ca22013-10-02 13:43:14 +0300308 /* We need to ensure that we set this back on if someone changed
309 * the scan mode through a raw HCI socket.
310 */
311 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
312
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200313 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
314 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200315
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200316 if (param & SCAN_INQUIRY) {
317 set_bit(HCI_ISCAN, &hdev->flags);
318 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200319 mgmt_discoverable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200320 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200321 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200322
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 if (param & SCAN_PAGE) {
324 set_bit(HCI_PSCAN, &hdev->flags);
325 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200328 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200329
330done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200331 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200332}
333
334static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
335{
336 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
337
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300338 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200339
340 if (rp->status)
341 return;
342
343 memcpy(hdev->dev_class, rp->dev_class, 3);
344
345 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300346 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200347}
348
349static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
350{
351 __u8 status = *((__u8 *) skb->data);
352 void *sent;
353
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300354 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200355
356 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
357 if (!sent)
358 return;
359
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100360 hci_dev_lock(hdev);
361
362 if (status == 0)
363 memcpy(hdev->dev_class, sent, 3);
364
365 if (test_bit(HCI_MGMT, &hdev->dev_flags))
366 mgmt_set_class_of_dev_complete(hdev, sent, status);
367
368 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200369}
370
371static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
372{
373 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300376 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200377
378 if (rp->status)
379 return;
380
381 setting = __le16_to_cpu(rp->voice_setting);
382
Marcel Holtmannf383f272008-07-14 20:13:47 +0200383 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384 return;
385
386 hdev->voice_setting = setting;
387
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300388 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200390 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200391 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392}
393
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300394static void hci_cc_write_voice_setting(struct hci_dev *hdev,
395 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200396{
397 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200398 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 void *sent;
400
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300401 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Marcel Holtmannf383f272008-07-14 20:13:47 +0200403 if (status)
404 return;
405
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200406 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
407 if (!sent)
408 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Marcel Holtmannf383f272008-07-14 20:13:47 +0200412 if (hdev->voice_setting == setting)
413 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Marcel Holtmannf383f272008-07-14 20:13:47 +0200415 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300417 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200418
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200419 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200420 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421}
422
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -0700423static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
424 struct sk_buff *skb)
425{
426 struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
427
428 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
429
430 if (rp->status)
431 return;
432
433 hdev->num_iac = rp->num_iac;
434
435 BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
436}
437
Marcel Holtmann333140b2008-07-14 20:13:48 +0200438static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
439{
440 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300441 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200442
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300443 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200444
Marcel Holtmann333140b2008-07-14 20:13:48 +0200445 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
446 if (!sent)
447 return;
448
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300449 if (!status) {
450 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300451 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300452 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300453 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300454 }
455
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200456 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300457 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200458 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300459 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200460 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
461 else
462 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
463 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200464}
465
Marcel Holtmanneac83dc2014-01-10 02:07:23 -0800466static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
467{
468 u8 status = *((u8 *) skb->data);
469 struct hci_cp_write_sc_support *sent;
470
471 BT_DBG("%s status 0x%2.2x", hdev->name, status);
472
473 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
474 if (!sent)
475 return;
476
477 if (!status) {
478 if (sent->support)
479 hdev->features[1][0] |= LMP_HOST_SC;
480 else
481 hdev->features[1][0] &= ~LMP_HOST_SC;
482 }
483
484 if (test_bit(HCI_MGMT, &hdev->dev_flags))
485 mgmt_sc_enable_complete(hdev, sent->support, status);
486 else if (!status) {
487 if (sent->support)
488 set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
489 else
490 clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
491 }
492}
493
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200494static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
495{
496 struct hci_rp_read_local_version *rp = (void *) skb->data;
497
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300498 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200499
500 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200501 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200502
Marcel Holtmann0d5551f2013-10-18 12:04:50 -0700503 if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
504 hdev->hci_ver = rp->hci_ver;
505 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
506 hdev->lmp_ver = rp->lmp_ver;
507 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
508 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
509 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200510}
511
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300512static void hci_cc_read_local_commands(struct hci_dev *hdev,
513 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200514{
515 struct hci_rp_read_local_commands *rp = (void *) skb->data;
516
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300517 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200518
Marcel Holtmann6a070e62013-10-31 04:54:33 -0700519 if (rp->status)
520 return;
521
522 if (test_bit(HCI_SETUP, &hdev->dev_flags))
Johan Hedberg2177bab2013-03-05 20:37:43 +0200523 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200524}
525
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300526static void hci_cc_read_local_features(struct hci_dev *hdev,
527 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200528{
529 struct hci_rp_read_local_features *rp = (void *) skb->data;
530
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300531 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200532
533 if (rp->status)
534 return;
535
536 memcpy(hdev->features, rp->features, 8);
537
538 /* Adjust default settings according to features
539 * supported by device. */
540
Johan Hedbergcad718e2013-04-17 15:00:51 +0300541 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200542 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
543
Johan Hedbergcad718e2013-04-17 15:00:51 +0300544 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200545 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
546
Johan Hedbergcad718e2013-04-17 15:00:51 +0300547 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200548 hdev->pkt_type |= (HCI_HV2);
549 hdev->esco_type |= (ESCO_HV2);
550 }
551
Johan Hedbergcad718e2013-04-17 15:00:51 +0300552 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200553 hdev->pkt_type |= (HCI_HV3);
554 hdev->esco_type |= (ESCO_HV3);
555 }
556
Andre Guedes45db810f2012-07-24 15:03:49 -0300557 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200558 hdev->esco_type |= (ESCO_EV3);
559
Johan Hedbergcad718e2013-04-17 15:00:51 +0300560 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200561 hdev->esco_type |= (ESCO_EV4);
562
Johan Hedbergcad718e2013-04-17 15:00:51 +0300563 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200564 hdev->esco_type |= (ESCO_EV5);
565
Johan Hedbergcad718e2013-04-17 15:00:51 +0300566 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100567 hdev->esco_type |= (ESCO_2EV3);
568
Johan Hedbergcad718e2013-04-17 15:00:51 +0300569 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100570 hdev->esco_type |= (ESCO_3EV3);
571
Johan Hedbergcad718e2013-04-17 15:00:51 +0300572 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100573 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200574}
575
Andre Guedes971e3a42011-06-30 19:20:52 -0300576static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300577 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300578{
579 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
580
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300581 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300582
583 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200584 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300585
Marcel Holtmann57af75a2013-10-18 12:04:47 -0700586 if (hdev->max_page < rp->max_page)
587 hdev->max_page = rp->max_page;
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300588
Johan Hedbergcad718e2013-04-17 15:00:51 +0300589 if (rp->page < HCI_MAX_PAGES)
590 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300591}
592
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200593static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300594 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200595{
596 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
597
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300598 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200599
Johan Hedberg42c6b122013-03-05 20:37:49 +0200600 if (!rp->status)
601 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200602}
603
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200604static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
605{
606 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
607
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300608 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200609
610 if (rp->status)
611 return;
612
613 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
614 hdev->sco_mtu = rp->sco_mtu;
615 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
616 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
617
618 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
619 hdev->sco_mtu = 64;
620 hdev->sco_pkts = 8;
621 }
622
623 hdev->acl_cnt = hdev->acl_pkts;
624 hdev->sco_cnt = hdev->sco_pkts;
625
Gustavo Padovan807deac2012-05-17 00:36:24 -0300626 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
627 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200628}
629
630static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
631{
632 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
633
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300634 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200635
636 if (!rp->status)
637 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200638}
639
Johan Hedbergf332ec62013-03-15 17:07:11 -0500640static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
641 struct sk_buff *skb)
642{
643 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
644
645 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
646
647 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
648 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
649 hdev->page_scan_window = __le16_to_cpu(rp->window);
650 }
651}
652
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500653static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
654 struct sk_buff *skb)
655{
656 u8 status = *((u8 *) skb->data);
657 struct hci_cp_write_page_scan_activity *sent;
658
659 BT_DBG("%s status 0x%2.2x", hdev->name, status);
660
661 if (status)
662 return;
663
664 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
665 if (!sent)
666 return;
667
668 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
669 hdev->page_scan_window = __le16_to_cpu(sent->window);
670}
671
Johan Hedbergf332ec62013-03-15 17:07:11 -0500672static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
673 struct sk_buff *skb)
674{
675 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
676
677 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
678
679 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
680 hdev->page_scan_type = rp->type;
681}
682
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500683static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
684 struct sk_buff *skb)
685{
686 u8 status = *((u8 *) skb->data);
687 u8 *type;
688
689 BT_DBG("%s status 0x%2.2x", hdev->name, status);
690
691 if (status)
692 return;
693
694 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
695 if (type)
696 hdev->page_scan_type = *type;
697}
698
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200699static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300700 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200701{
702 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
703
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300704 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200705
706 if (rp->status)
707 return;
708
709 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
710 hdev->block_len = __le16_to_cpu(rp->block_len);
711 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
712
713 hdev->block_cnt = hdev->num_blocks;
714
715 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300716 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200717}
718
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300719static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300720 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300721{
722 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
723
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300724 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300725
726 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300727 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300728
729 hdev->amp_status = rp->amp_status;
730 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
731 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
732 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
733 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
734 hdev->amp_type = rp->amp_type;
735 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
736 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
737 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
738 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
739
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300740a2mp_rsp:
741 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300742}
743
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300744static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
745 struct sk_buff *skb)
746{
747 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
748 struct amp_assoc *assoc = &hdev->loc_assoc;
749 size_t rem_len, frag_len;
750
751 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
752
753 if (rp->status)
754 goto a2mp_rsp;
755
756 frag_len = skb->len - sizeof(*rp);
757 rem_len = __le16_to_cpu(rp->rem_len);
758
759 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300760 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300761
762 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
763 assoc->offset += frag_len;
764
765 /* Read other fragments */
766 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
767
768 return;
769 }
770
771 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
772 assoc->len = assoc->offset + rem_len;
773 assoc->offset = 0;
774
775a2mp_rsp:
776 /* Send A2MP Rsp when all fragments are received */
777 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300778 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300779}
780
Johan Hedbergd5859e22011-01-25 01:19:58 +0200781static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300782 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200783{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700784 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200785
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300786 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200787
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700788 if (!rp->status)
789 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200790}
791
Johan Hedberg980e1a52011-01-22 06:10:07 +0200792static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
793{
794 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
795 struct hci_cp_pin_code_reply *cp;
796 struct hci_conn *conn;
797
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300798 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200799
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200800 hci_dev_lock(hdev);
801
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200802 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200803 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200804
Mikel Astizfa1bd912012-08-09 09:52:29 +0200805 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200806 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200807
808 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
809 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200810 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200811
812 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
813 if (conn)
814 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200815
816unlock:
817 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200818}
819
820static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
821{
822 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
823
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300824 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200825
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200826 hci_dev_lock(hdev);
827
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200828 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200829 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300830 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200831
832 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200833}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200834
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300835static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
836 struct sk_buff *skb)
837{
838 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
839
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300840 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300841
842 if (rp->status)
843 return;
844
845 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
846 hdev->le_pkts = rp->le_max_pkt;
847
848 hdev->le_cnt = hdev->le_pkts;
849
850 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300851}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200852
Johan Hedberg60e77322013-01-22 14:01:59 +0200853static void hci_cc_le_read_local_features(struct hci_dev *hdev,
854 struct sk_buff *skb)
855{
856 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
857
858 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
859
860 if (!rp->status)
861 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200862}
863
Johan Hedberg8fa19092012-10-19 20:57:49 +0300864static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
865 struct sk_buff *skb)
866{
867 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
868
869 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
870
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500871 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300872 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300873}
874
Johan Hedberga5c29682011-02-19 12:05:57 -0300875static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
876{
877 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
878
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300879 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300880
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200881 hci_dev_lock(hdev);
882
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200883 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300884 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
885 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200886
887 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300888}
889
890static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300891 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300892{
893 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
894
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300895 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300896
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200897 hci_dev_lock(hdev);
898
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200899 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200900 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300901 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200902
903 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300904}
905
Brian Gix1143d452011-11-23 08:28:34 -0800906static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
907{
908 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
909
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300910 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800911
912 hci_dev_lock(hdev);
913
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200914 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200915 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300916 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800917
918 hci_dev_unlock(hdev);
919}
920
921static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300922 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800923{
924 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
925
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300926 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800927
928 hci_dev_lock(hdev);
929
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200930 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800931 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300932 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800933
934 hci_dev_unlock(hdev);
935}
936
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800937static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
938 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100939{
940 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
941
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300942 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100943
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200944 hci_dev_lock(hdev);
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800945 mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer,
946 NULL, NULL, rp->status);
947 hci_dev_unlock(hdev);
948}
949
950static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
951 struct sk_buff *skb)
952{
953 struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data;
954
955 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
956
957 hci_dev_lock(hdev);
958 mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192,
959 rp->hash256, rp->randomizer256,
960 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200961 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100962}
963
Marcel Holtmann7a4cd512014-02-19 19:52:13 -0800964
965static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
966{
967 __u8 status = *((__u8 *) skb->data);
968 bdaddr_t *sent;
969
970 BT_DBG("%s status 0x%2.2x", hdev->name, status);
971
972 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
973 if (!sent)
974 return;
975
976 hci_dev_lock(hdev);
977
978 if (!status)
979 bacpy(&hdev->random_addr, sent);
980
981 hci_dev_unlock(hdev);
982}
983
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100984static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
985{
986 __u8 *sent, status = *((__u8 *) skb->data);
987
988 BT_DBG("%s status 0x%2.2x", hdev->name, status);
989
990 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
991 if (!sent)
992 return;
993
Johan Hedberg3c857752014-03-25 10:30:49 +0200994 if (status)
995 return;
996
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100997 hci_dev_lock(hdev);
998
Johan Hedberg3c857752014-03-25 10:30:49 +0200999 /* If we're doing connection initation as peripheral. Set a
1000 * timeout in case something goes wrong.
1001 */
1002 if (*sent) {
1003 struct hci_conn *conn;
1004
1005 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
1006 if (conn)
1007 queue_delayed_work(hdev->workqueue,
1008 &conn->le_conn_timeout,
1009 HCI_LE_CONN_TIMEOUT);
1010 }
1011
1012 mgmt_advertising(hdev, *sent);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01001013
Johan Hedberg04b4edc2013-03-15 17:07:01 -05001014 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01001015}
1016
Marcel Holtmann533553f2014-03-21 12:18:10 -07001017static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1018{
1019 struct hci_cp_le_set_scan_param *cp;
1020 __u8 status = *((__u8 *) skb->data);
1021
1022 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1023
1024 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
1025 if (!cp)
1026 return;
1027
1028 hci_dev_lock(hdev);
1029
1030 if (!status)
1031 hdev->le_scan_type = cp->type;
1032
1033 hci_dev_unlock(hdev);
1034}
1035
Johan Hedbergb9a63282014-03-25 10:51:52 +02001036static bool has_pending_adv_report(struct hci_dev *hdev)
1037{
1038 struct discovery_state *d = &hdev->discovery;
1039
1040 return bacmp(&d->last_adv_addr, BDADDR_ANY);
1041}
1042
1043static void clear_pending_adv_report(struct hci_dev *hdev)
1044{
1045 struct discovery_state *d = &hdev->discovery;
1046
1047 bacpy(&d->last_adv_addr, BDADDR_ANY);
1048 d->last_adv_data_len = 0;
1049}
1050
1051static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
Johan Hedbergff5cd292014-03-25 14:40:52 +02001052 u8 bdaddr_type, s8 rssi, u8 *data, u8 len)
Johan Hedbergb9a63282014-03-25 10:51:52 +02001053{
1054 struct discovery_state *d = &hdev->discovery;
1055
1056 bacpy(&d->last_adv_addr, bdaddr);
1057 d->last_adv_addr_type = bdaddr_type;
Johan Hedbergff5cd292014-03-25 14:40:52 +02001058 d->last_adv_rssi = rssi;
Johan Hedbergb9a63282014-03-25 10:51:52 +02001059 memcpy(d->last_adv_data, data, len);
1060 d->last_adv_data_len = len;
1061}
1062
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001063static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001064 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001065{
1066 struct hci_cp_le_set_scan_enable *cp;
1067 __u8 status = *((__u8 *) skb->data);
1068
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001069 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001070
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001071 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1072 if (!cp)
1073 return;
1074
Andre Guedes3fd319b2013-04-30 15:29:36 -03001075 if (status)
1076 return;
1077
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001078 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -03001079 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -03001080 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Johan Hedbergb9a63282014-03-25 10:51:52 +02001081 if (hdev->le_scan_type == LE_SCAN_ACTIVE)
1082 clear_pending_adv_report(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001083 break;
1084
Andre Guedes76a388b2013-04-04 20:21:02 -03001085 case LE_SCAN_DISABLE:
Johan Hedbergb9a63282014-03-25 10:51:52 +02001086 /* We do this here instead of when setting DISCOVERY_STOPPED
1087 * since the latter would potentially require waiting for
1088 * inquiry to stop too.
1089 */
1090 if (has_pending_adv_report(hdev)) {
1091 struct discovery_state *d = &hdev->discovery;
1092
1093 mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
1094 d->last_adv_addr_type, NULL, 0, 0,
1095 1, d->last_adv_data,
1096 d->last_adv_data_len, NULL, 0);
1097 }
1098
Johan Hedberg317ac8c2014-02-28 20:26:12 +02001099 /* Cancel this timer so that we don't try to disable scanning
1100 * when it's already disabled.
1101 */
1102 cancel_delayed_work(&hdev->le_scan_disable);
1103
Andre Guedesd23264a2011-11-25 20:53:38 -03001104 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Johan Hedberg81ad6fd2014-02-28 20:26:13 +02001105 /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
1106 * interrupted scanning due to a connect request. Mark
1107 * therefore discovery as stopped.
1108 */
1109 if (test_and_clear_bit(HCI_LE_SCAN_INTERRUPTED,
1110 &hdev->dev_flags))
1111 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001112 break;
1113
1114 default:
1115 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1116 break;
Andre Guedes35815082011-05-26 16:23:53 -03001117 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001118}
1119
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001120static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1121 struct sk_buff *skb)
1122{
1123 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1124
1125 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1126
1127 if (!rp->status)
1128 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001129}
1130
Marcel Holtmann0f36b582014-02-27 20:37:31 -08001131static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
1132 struct sk_buff *skb)
1133{
1134 __u8 status = *((__u8 *) skb->data);
1135
1136 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1137
1138 if (!status)
1139 hci_white_list_clear(hdev);
1140}
1141
1142static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
1143 struct sk_buff *skb)
1144{
1145 struct hci_cp_le_add_to_white_list *sent;
1146 __u8 status = *((__u8 *) skb->data);
1147
1148 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1149
1150 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST);
1151 if (!sent)
1152 return;
1153
1154 if (!status)
1155 hci_white_list_add(hdev, &sent->bdaddr, sent->bdaddr_type);
1156}
1157
1158static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
1159 struct sk_buff *skb)
1160{
1161 struct hci_cp_le_del_from_white_list *sent;
1162 __u8 status = *((__u8 *) skb->data);
1163
1164 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1165
1166 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST);
1167 if (!sent)
1168 return;
1169
1170 if (!status)
1171 hci_white_list_del(hdev, &sent->bdaddr, sent->bdaddr_type);
1172}
1173
Johan Hedberg9b008c02013-01-22 14:02:01 +02001174static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1175 struct sk_buff *skb)
1176{
1177 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1178
1179 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1180
1181 if (!rp->status)
1182 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001183}
1184
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001185static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1186 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001187{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001188 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001189 __u8 status = *((__u8 *) skb->data);
1190
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001191 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001192
Johan Hedberg06199cf2012-02-22 16:37:11 +02001193 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001194 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001195 return;
1196
Johan Hedberg8f984df2012-02-28 01:07:22 +02001197 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001198 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001199 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001200 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1201 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001202 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001203 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001204 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001205 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001206
1207 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001208 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001209 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001210 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001211 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001212}
1213
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02001214static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
1215{
1216 struct hci_cp_le_set_adv_param *cp;
1217 u8 status = *((u8 *) skb->data);
1218
1219 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1220
1221 if (status)
1222 return;
1223
1224 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
1225 if (!cp)
1226 return;
1227
1228 hci_dev_lock(hdev);
1229 hdev->adv_addr_type = cp->own_address_type;
1230 hci_dev_unlock(hdev);
1231}
1232
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001233static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1234 struct sk_buff *skb)
1235{
1236 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1237
1238 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1239 hdev->name, rp->status, rp->phy_handle);
1240
1241 if (rp->status)
1242 return;
1243
1244 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1245}
1246
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001247static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001248{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001249 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001250
1251 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001252 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001253 return;
1254 }
1255
Andre Guedes89352e72011-11-04 14:16:53 -03001256 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001257}
1258
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001259static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001261 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001264 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001265
1266 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 if (!cp)
1268 return;
1269
1270 hci_dev_lock(hdev);
1271
1272 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1273
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001274 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275
1276 if (status) {
1277 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001278 if (status != 0x0c || conn->attempt > 2) {
1279 conn->state = BT_CLOSED;
1280 hci_proto_connect_cfm(conn, status);
1281 hci_conn_del(conn);
1282 } else
1283 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 }
1285 } else {
1286 if (!conn) {
1287 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1288 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001289 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290 conn->link_mode |= HCI_LM_MASTER;
1291 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001292 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293 }
1294 }
1295
1296 hci_dev_unlock(hdev);
1297}
1298
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001299static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001301 struct hci_cp_add_sco *cp;
1302 struct hci_conn *acl, *sco;
1303 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001305 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001306
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001307 if (!status)
1308 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001310 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1311 if (!cp)
1312 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001314 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001316 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001317
1318 hci_dev_lock(hdev);
1319
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001320 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001321 if (acl) {
1322 sco = acl->link;
1323 if (sco) {
1324 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001325
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001326 hci_proto_connect_cfm(sco, status);
1327 hci_conn_del(sco);
1328 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001329 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001330
1331 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332}
1333
Marcel Holtmannf8558552008-07-14 20:13:49 +02001334static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1335{
1336 struct hci_cp_auth_requested *cp;
1337 struct hci_conn *conn;
1338
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001339 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001340
1341 if (!status)
1342 return;
1343
1344 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1345 if (!cp)
1346 return;
1347
1348 hci_dev_lock(hdev);
1349
1350 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1351 if (conn) {
1352 if (conn->state == BT_CONFIG) {
1353 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001354 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001355 }
1356 }
1357
1358 hci_dev_unlock(hdev);
1359}
1360
1361static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1362{
1363 struct hci_cp_set_conn_encrypt *cp;
1364 struct hci_conn *conn;
1365
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001366 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001367
1368 if (!status)
1369 return;
1370
1371 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1372 if (!cp)
1373 return;
1374
1375 hci_dev_lock(hdev);
1376
1377 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1378 if (conn) {
1379 if (conn->state == BT_CONFIG) {
1380 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001381 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001382 }
1383 }
1384
1385 hci_dev_unlock(hdev);
1386}
1387
Johan Hedberg127178d2010-11-18 22:22:29 +02001388static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001389 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001390{
Johan Hedberg392599b2010-11-18 22:22:28 +02001391 if (conn->state != BT_CONFIG || !conn->out)
1392 return 0;
1393
Johan Hedberg765c2a92011-01-19 12:06:52 +05301394 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001395 return 0;
1396
1397 /* Only request authentication for SSP connections or non-SSP
Johan Hedberg264b8b42014-01-08 16:40:39 +02001398 * devices with sec_level MEDIUM or HIGH or if MITM protection
1399 * is requested.
1400 */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001401 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
Johan Hedberg264b8b42014-01-08 16:40:39 +02001402 conn->pending_sec_level != BT_SECURITY_HIGH &&
1403 conn->pending_sec_level != BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001404 return 0;
1405
Johan Hedberg392599b2010-11-18 22:22:28 +02001406 return 1;
1407}
1408
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001409static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001410 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001411{
1412 struct hci_cp_remote_name_req cp;
1413
1414 memset(&cp, 0, sizeof(cp));
1415
1416 bacpy(&cp.bdaddr, &e->data.bdaddr);
1417 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1418 cp.pscan_mode = e->data.pscan_mode;
1419 cp.clock_offset = e->data.clock_offset;
1420
1421 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1422}
1423
Johan Hedbergb644ba32012-01-17 21:48:47 +02001424static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001425{
1426 struct discovery_state *discov = &hdev->discovery;
1427 struct inquiry_entry *e;
1428
Johan Hedbergb644ba32012-01-17 21:48:47 +02001429 if (list_empty(&discov->resolve))
1430 return false;
1431
1432 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001433 if (!e)
1434 return false;
1435
Johan Hedbergb644ba32012-01-17 21:48:47 +02001436 if (hci_resolve_name(hdev, e) == 0) {
1437 e->name_state = NAME_PENDING;
1438 return true;
1439 }
1440
1441 return false;
1442}
1443
1444static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001445 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001446{
1447 struct discovery_state *discov = &hdev->discovery;
1448 struct inquiry_entry *e;
1449
1450 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001451 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1452 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001453
1454 if (discov->state == DISCOVERY_STOPPED)
1455 return;
1456
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001457 if (discov->state == DISCOVERY_STOPPING)
1458 goto discov_complete;
1459
1460 if (discov->state != DISCOVERY_RESOLVING)
1461 return;
1462
1463 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001464 /* If the device was not found in a list of found devices names of which
1465 * are pending. there is no need to continue resolving a next name as it
1466 * will be done upon receiving another Remote Name Request Complete
1467 * Event */
1468 if (!e)
1469 return;
1470
1471 list_del(&e->list);
1472 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001473 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001474 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1475 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001476 } else {
1477 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001478 }
1479
Johan Hedbergb644ba32012-01-17 21:48:47 +02001480 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001481 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001482
1483discov_complete:
1484 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1485}
1486
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001487static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1488{
Johan Hedberg127178d2010-11-18 22:22:29 +02001489 struct hci_cp_remote_name_req *cp;
1490 struct hci_conn *conn;
1491
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001492 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001493
1494 /* If successful wait for the name req complete event before
1495 * checking for the need to do authentication */
1496 if (!status)
1497 return;
1498
1499 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1500 if (!cp)
1501 return;
1502
1503 hci_dev_lock(hdev);
1504
1505 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001506
1507 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1508 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1509
Johan Hedberg79c6c702011-04-28 11:28:55 -07001510 if (!conn)
1511 goto unlock;
1512
1513 if (!hci_outgoing_auth_needed(hdev, conn))
1514 goto unlock;
1515
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001516 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001517 struct hci_cp_auth_requested auth_cp;
1518
1519 auth_cp.handle = __cpu_to_le16(conn->handle);
1520 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1521 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001522 }
1523
Johan Hedberg79c6c702011-04-28 11:28:55 -07001524unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001525 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001526}
1527
Marcel Holtmann769be972008-07-14 20:13:49 +02001528static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1529{
1530 struct hci_cp_read_remote_features *cp;
1531 struct hci_conn *conn;
1532
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001533 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001534
1535 if (!status)
1536 return;
1537
1538 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1539 if (!cp)
1540 return;
1541
1542 hci_dev_lock(hdev);
1543
1544 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1545 if (conn) {
1546 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001547 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001548 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001549 }
1550 }
1551
1552 hci_dev_unlock(hdev);
1553}
1554
1555static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1556{
1557 struct hci_cp_read_remote_ext_features *cp;
1558 struct hci_conn *conn;
1559
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001560 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001561
1562 if (!status)
1563 return;
1564
1565 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1566 if (!cp)
1567 return;
1568
1569 hci_dev_lock(hdev);
1570
1571 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1572 if (conn) {
1573 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001574 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001575 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001576 }
1577 }
1578
1579 hci_dev_unlock(hdev);
1580}
1581
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001582static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1583{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001584 struct hci_cp_setup_sync_conn *cp;
1585 struct hci_conn *acl, *sco;
1586 __u16 handle;
1587
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001588 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001589
1590 if (!status)
1591 return;
1592
1593 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1594 if (!cp)
1595 return;
1596
1597 handle = __le16_to_cpu(cp->handle);
1598
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001599 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001600
1601 hci_dev_lock(hdev);
1602
1603 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001604 if (acl) {
1605 sco = acl->link;
1606 if (sco) {
1607 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001608
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001609 hci_proto_connect_cfm(sco, status);
1610 hci_conn_del(sco);
1611 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001612 }
1613
1614 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001615}
1616
1617static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1618{
1619 struct hci_cp_sniff_mode *cp;
1620 struct hci_conn *conn;
1621
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001622 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001623
1624 if (!status)
1625 return;
1626
1627 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1628 if (!cp)
1629 return;
1630
1631 hci_dev_lock(hdev);
1632
1633 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001634 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001635 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001636
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001637 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001638 hci_sco_setup(conn, status);
1639 }
1640
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001641 hci_dev_unlock(hdev);
1642}
1643
1644static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1645{
1646 struct hci_cp_exit_sniff_mode *cp;
1647 struct hci_conn *conn;
1648
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001649 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001650
1651 if (!status)
1652 return;
1653
1654 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1655 if (!cp)
1656 return;
1657
1658 hci_dev_lock(hdev);
1659
1660 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001661 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001662 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001663
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001664 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001665 hci_sco_setup(conn, status);
1666 }
1667
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001668 hci_dev_unlock(hdev);
1669}
1670
Johan Hedberg88c3df12012-02-09 14:27:38 +02001671static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1672{
1673 struct hci_cp_disconnect *cp;
1674 struct hci_conn *conn;
1675
1676 if (!status)
1677 return;
1678
1679 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1680 if (!cp)
1681 return;
1682
1683 hci_dev_lock(hdev);
1684
1685 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1686 if (conn)
1687 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001688 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001689
1690 hci_dev_unlock(hdev);
1691}
1692
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001693static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1694{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001695 struct hci_cp_create_phy_link *cp;
1696
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001697 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001698
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001699 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1700 if (!cp)
1701 return;
1702
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001703 hci_dev_lock(hdev);
1704
1705 if (status) {
1706 struct hci_conn *hcon;
1707
1708 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1709 if (hcon)
1710 hci_conn_del(hcon);
1711 } else {
1712 amp_write_remote_assoc(hdev, cp->phy_handle);
1713 }
1714
1715 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001716}
1717
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001718static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1719{
1720 struct hci_cp_accept_phy_link *cp;
1721
1722 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1723
1724 if (status)
1725 return;
1726
1727 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1728 if (!cp)
1729 return;
1730
1731 amp_write_remote_assoc(hdev, cp->phy_handle);
1732}
1733
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001734static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
1735{
1736 struct hci_cp_le_create_conn *cp;
1737 struct hci_conn *conn;
1738
1739 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1740
1741 /* All connection failure handling is taken care of by the
1742 * hci_le_conn_failed function which is triggered by the HCI
1743 * request completion callbacks used for connecting.
1744 */
1745 if (status)
1746 return;
1747
1748 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1749 if (!cp)
1750 return;
1751
1752 hci_dev_lock(hdev);
1753
1754 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1755 if (!conn)
1756 goto unlock;
1757
1758 /* Store the initiator and responder address information which
1759 * is needed for SMP. These values will not change during the
1760 * lifetime of the connection.
1761 */
1762 conn->init_addr_type = cp->own_address_type;
1763 if (cp->own_address_type == ADDR_LE_DEV_RANDOM)
1764 bacpy(&conn->init_addr, &hdev->random_addr);
1765 else
1766 bacpy(&conn->init_addr, &hdev->bdaddr);
1767
1768 conn->resp_addr_type = cp->peer_addr_type;
1769 bacpy(&conn->resp_addr, &cp->peer_addr);
1770
Johan Hedberg9489eca2014-02-28 17:45:46 +02001771 /* We don't want the connection attempt to stick around
1772 * indefinitely since LE doesn't have a page timeout concept
1773 * like BR/EDR. Set a timer for any connection that doesn't use
1774 * the white list for connecting.
1775 */
1776 if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
1777 queue_delayed_work(conn->hdev->workqueue,
1778 &conn->le_conn_timeout,
1779 HCI_LE_CONN_TIMEOUT);
1780
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001781unlock:
1782 hci_dev_unlock(hdev);
1783}
1784
Johan Hedberg81d0c8a2014-03-24 14:39:04 +02001785static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1786{
1787 struct hci_cp_le_start_enc *cp;
1788 struct hci_conn *conn;
1789
1790 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1791
1792 if (!status)
1793 return;
1794
1795 hci_dev_lock(hdev);
1796
1797 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
1798 if (!cp)
1799 goto unlock;
1800
1801 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1802 if (!conn)
1803 goto unlock;
1804
1805 if (conn->state != BT_CONNECTED)
1806 goto unlock;
1807
1808 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
1809 hci_conn_drop(conn);
1810
1811unlock:
1812 hci_dev_unlock(hdev);
1813}
1814
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001815static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001816{
1817 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001818 struct discovery_state *discov = &hdev->discovery;
1819 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001820
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001821 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001822
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001823 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001824
1825 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1826 return;
1827
Andre Guedes3e13fa12013-03-27 20:04:56 -03001828 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1829 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1830
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001831 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001832 return;
1833
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001834 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001835
Andre Guedes343f9352012-02-17 20:39:37 -03001836 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001837 goto unlock;
1838
1839 if (list_empty(&discov->resolve)) {
1840 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1841 goto unlock;
1842 }
1843
1844 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1845 if (e && hci_resolve_name(hdev, e) == 0) {
1846 e->name_state = NAME_PENDING;
1847 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1848 } else {
1849 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1850 }
1851
1852unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001853 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001854}
1855
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001856static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001858 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001859 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860 int num_rsp = *((__u8 *) skb->data);
1861
1862 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1863
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001864 if (!num_rsp)
1865 return;
1866
Andre Guedes1519cc12012-03-21 00:03:38 -03001867 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1868 return;
1869
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001871
Johan Hedberge17acd42011-03-30 23:57:16 +03001872 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001873 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001874
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875 bacpy(&data.bdaddr, &info->bdaddr);
1876 data.pscan_rep_mode = info->pscan_rep_mode;
1877 data.pscan_period_mode = info->pscan_period_mode;
1878 data.pscan_mode = info->pscan_mode;
1879 memcpy(data.dev_class, info->dev_class, 3);
1880 data.clock_offset = info->clock_offset;
1881 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001882 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001883
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001884 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001885 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001886 info->dev_class, 0, !name_known, ssp, NULL,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02001887 0, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001889
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 hci_dev_unlock(hdev);
1891}
1892
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001893static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001895 struct hci_ev_conn_complete *ev = (void *) skb->data;
1896 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001898 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001899
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001901
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001902 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001903 if (!conn) {
1904 if (ev->link_type != SCO_LINK)
1905 goto unlock;
1906
1907 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1908 if (!conn)
1909 goto unlock;
1910
1911 conn->type = SCO_LINK;
1912 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001913
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001914 if (!ev->status) {
1915 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001916
1917 if (conn->type == ACL_LINK) {
1918 conn->state = BT_CONFIG;
1919 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001920
1921 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1922 !hci_find_link_key(hdev, &ev->bdaddr))
1923 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1924 else
1925 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001926 } else
1927 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001928
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001929 hci_conn_add_sysfs(conn);
1930
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001931 if (test_bit(HCI_AUTH, &hdev->flags))
1932 conn->link_mode |= HCI_LM_AUTH;
1933
1934 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1935 conn->link_mode |= HCI_LM_ENCRYPT;
1936
1937 /* Get remote features */
1938 if (conn->type == ACL_LINK) {
1939 struct hci_cp_read_remote_features cp;
1940 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001941 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001942 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001943 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001944
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001945 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001946 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001947 struct hci_cp_change_conn_ptype cp;
1948 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001949 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001950 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1951 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001952 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001953 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001954 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001955 if (conn->type == ACL_LINK)
Marcel Holtmann64c7b772014-02-18 14:22:20 -08001956 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001957 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001958 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001959
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001960 if (conn->type == ACL_LINK)
1961 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001962
Marcel Holtmann769be972008-07-14 20:13:49 +02001963 if (ev->status) {
1964 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001965 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001966 } else if (ev->link_type != ACL_LINK)
1967 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001968
1969unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001971
1972 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973}
1974
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001975static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001977 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001979 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001981 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001982 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001984 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1985 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986
Szymon Janc138d22e2011-02-17 16:44:23 +01001987 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07001988 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001990 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001992
1993 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001994
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001995 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1996 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001997 memcpy(ie->data.dev_class, ev->dev_class, 3);
1998
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001999 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
2000 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002001 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002002 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
2003 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03002004 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005 hci_dev_unlock(hdev);
2006 return;
2007 }
2008 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002009
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002011
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012 hci_dev_unlock(hdev);
2013
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002014 if (ev->link_type == ACL_LINK ||
2015 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002016 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002017 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002019 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002021 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
2022 cp.role = 0x00; /* Become master */
2023 else
2024 cp.role = 0x01; /* Remain slave */
2025
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002026 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
2027 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002028 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002029 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002030 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002031
2032 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002033 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002034
Joe Perchesdcf4adb2014-03-12 10:52:35 -07002035 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
2036 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
2037 cp.max_latency = cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002038 cp.content_format = cpu_to_le16(hdev->voice_setting);
2039 cp.retrans_effort = 0xff;
2040
2041 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002042 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002043 } else {
2044 conn->state = BT_CONNECT2;
2045 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002046 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 } else {
2048 /* Connection rejected */
2049 struct hci_cp_reject_conn_req cp;
2050
2051 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002052 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002053 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054 }
2055}
2056
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02002057static u8 hci_to_mgmt_reason(u8 err)
2058{
2059 switch (err) {
2060 case HCI_ERROR_CONNECTION_TIMEOUT:
2061 return MGMT_DEV_DISCONN_TIMEOUT;
2062 case HCI_ERROR_REMOTE_USER_TERM:
2063 case HCI_ERROR_REMOTE_LOW_RESOURCES:
2064 case HCI_ERROR_REMOTE_POWER_OFF:
2065 return MGMT_DEV_DISCONN_REMOTE;
2066 case HCI_ERROR_LOCAL_HOST_TERM:
2067 return MGMT_DEV_DISCONN_LOCAL_HOST;
2068 default:
2069 return MGMT_DEV_DISCONN_UNKNOWN;
2070 }
2071}
2072
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002073static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002075 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03002076 u8 reason = hci_to_mgmt_reason(ev->reason);
Andre Guedes9fcb18e2014-02-26 20:21:48 -03002077 struct hci_conn_params *params;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002078 struct hci_conn *conn;
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02002079 bool mgmt_connected;
Andre Guedes38462202013-11-07 17:36:10 -03002080 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002082 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084 hci_dev_lock(hdev);
2085
Marcel Holtmann04837f62006-07-03 10:02:33 +02002086 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02002087 if (!conn)
2088 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002089
Andre Guedesabf54a52013-11-07 17:36:09 -03002090 if (ev->status) {
2091 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
2092 conn->dst_type, ev->status);
2093 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002094 }
Johan Hedbergf7520542011-01-20 12:34:39 +02002095
Andre Guedes38462202013-11-07 17:36:10 -03002096 conn->state = BT_CLOSED;
2097
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02002098 mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
2099 mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
2100 reason, mgmt_connected);
Andre Guedesabf54a52013-11-07 17:36:09 -03002101
Andre Guedes38462202013-11-07 17:36:10 -03002102 if (conn->type == ACL_LINK && conn->flush_key)
2103 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg22102462013-10-05 12:01:06 +02002104
Andre Guedes9fcb18e2014-02-26 20:21:48 -03002105 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
2106 if (params) {
2107 switch (params->auto_connect) {
2108 case HCI_AUTO_CONN_LINK_LOSS:
2109 if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
2110 break;
2111 /* Fall through */
2112
2113 case HCI_AUTO_CONN_ALWAYS:
2114 hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
2115 break;
2116
2117 default:
2118 break;
2119 }
2120 }
2121
Andre Guedes38462202013-11-07 17:36:10 -03002122 type = conn->type;
Johan Hedberg22102462013-10-05 12:01:06 +02002123
Andre Guedes38462202013-11-07 17:36:10 -03002124 hci_proto_disconn_cfm(conn, ev->reason);
2125 hci_conn_del(conn);
2126
2127 /* Re-enable advertising if necessary, since it might
2128 * have been disabled by the connection. From the
2129 * HCI_LE_Set_Advertise_Enable command description in
2130 * the core specification (v4.0):
2131 * "The Controller shall continue advertising until the Host
2132 * issues an LE_Set_Advertise_Enable command with
2133 * Advertising_Enable set to 0x00 (Advertising is disabled)
2134 * or until a connection is created or until the Advertising
2135 * is timed out due to Directed Advertising."
2136 */
2137 if (type == LE_LINK)
2138 mgmt_reenable_advertising(hdev);
Johan Hedbergf7520542011-01-20 12:34:39 +02002139
2140unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141 hci_dev_unlock(hdev);
2142}
2143
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002144static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002145{
2146 struct hci_ev_auth_complete *ev = (void *) skb->data;
2147 struct hci_conn *conn;
2148
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002149 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002150
2151 hci_dev_lock(hdev);
2152
2153 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002154 if (!conn)
2155 goto unlock;
2156
2157 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002158 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002159 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002160 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03002161 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002162 conn->link_mode |= HCI_LM_AUTH;
2163 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03002164 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002165 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02002166 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002167 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002168 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002169
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002170 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
2171 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002172
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002173 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002174 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002175 struct hci_cp_set_conn_encrypt cp;
2176 cp.handle = ev->handle;
2177 cp.encrypt = 0x01;
2178 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002179 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002180 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002181 conn->state = BT_CONNECTED;
2182 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002183 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002184 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002185 } else {
2186 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002187
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002188 hci_conn_hold(conn);
2189 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002190 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002191 }
2192
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002193 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002194 if (!ev->status) {
2195 struct hci_cp_set_conn_encrypt cp;
2196 cp.handle = ev->handle;
2197 cp.encrypt = 0x01;
2198 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002199 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002200 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002201 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002202 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002203 }
2204 }
2205
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002206unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002207 hci_dev_unlock(hdev);
2208}
2209
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002210static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002211{
Johan Hedberg127178d2010-11-18 22:22:29 +02002212 struct hci_ev_remote_name *ev = (void *) skb->data;
2213 struct hci_conn *conn;
2214
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002215 BT_DBG("%s", hdev->name);
2216
2217 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002218
2219 hci_dev_lock(hdev);
2220
2221 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002222
2223 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2224 goto check_auth;
2225
2226 if (ev->status == 0)
2227 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002228 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002229 else
2230 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2231
2232check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002233 if (!conn)
2234 goto unlock;
2235
2236 if (!hci_outgoing_auth_needed(hdev, conn))
2237 goto unlock;
2238
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002239 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002240 struct hci_cp_auth_requested cp;
2241 cp.handle = __cpu_to_le16(conn->handle);
2242 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2243 }
2244
Johan Hedberg79c6c702011-04-28 11:28:55 -07002245unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002246 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002247}
2248
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002249static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002250{
2251 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2252 struct hci_conn *conn;
2253
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002254 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002255
2256 hci_dev_lock(hdev);
2257
2258 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002259 if (!conn)
2260 goto unlock;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002261
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002262 if (!ev->status) {
2263 if (ev->encrypt) {
2264 /* Encryption implies authentication */
2265 conn->link_mode |= HCI_LM_AUTH;
2266 conn->link_mode |= HCI_LM_ENCRYPT;
2267 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002268
Marcel Holtmann914a6ff2014-02-01 11:52:02 -08002269 /* P-256 authentication key implies FIPS */
2270 if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
2271 conn->link_mode |= HCI_LM_FIPS;
2272
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002273 if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2274 conn->type == LE_LINK)
2275 set_bit(HCI_CONN_AES_CCM, &conn->flags);
2276 } else {
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002277 conn->link_mode &= ~HCI_LM_ENCRYPT;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002278 clear_bit(HCI_CONN_AES_CCM, &conn->flags);
2279 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002280 }
2281
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002282 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2283
2284 if (ev->status && conn->state == BT_CONNECTED) {
2285 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
2286 hci_conn_drop(conn);
2287 goto unlock;
2288 }
2289
2290 if (conn->state == BT_CONFIG) {
2291 if (!ev->status)
2292 conn->state = BT_CONNECTED;
2293
Marcel Holtmann40b552a2014-03-19 14:10:25 -07002294 /* In Secure Connections Only mode, do not allow any
2295 * connections that are not encrypted with AES-CCM
2296 * using a P-256 authenticated combination key.
2297 */
2298 if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) &&
2299 (!test_bit(HCI_CONN_AES_CCM, &conn->flags) ||
2300 conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) {
2301 hci_proto_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE);
2302 hci_conn_drop(conn);
2303 goto unlock;
2304 }
2305
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002306 hci_proto_connect_cfm(conn, ev->status);
2307 hci_conn_drop(conn);
2308 } else
2309 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2310
Gustavo Padovana7d77232012-05-13 03:20:07 -03002311unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002312 hci_dev_unlock(hdev);
2313}
2314
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002315static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2316 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002317{
2318 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2319 struct hci_conn *conn;
2320
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002321 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002322
2323 hci_dev_lock(hdev);
2324
2325 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2326 if (conn) {
2327 if (!ev->status)
2328 conn->link_mode |= HCI_LM_SECURE;
2329
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002330 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002331
2332 hci_key_change_cfm(conn, ev->status);
2333 }
2334
2335 hci_dev_unlock(hdev);
2336}
2337
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002338static void hci_remote_features_evt(struct hci_dev *hdev,
2339 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002340{
2341 struct hci_ev_remote_features *ev = (void *) skb->data;
2342 struct hci_conn *conn;
2343
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002344 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002345
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002346 hci_dev_lock(hdev);
2347
2348 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002349 if (!conn)
2350 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002351
Johan Hedbergccd556f2010-11-10 17:11:51 +02002352 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002353 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002354
2355 if (conn->state != BT_CONFIG)
2356 goto unlock;
2357
2358 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2359 struct hci_cp_read_remote_ext_features cp;
2360 cp.handle = ev->handle;
2361 cp.page = 0x01;
2362 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002363 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002364 goto unlock;
2365 }
2366
Johan Hedberg671267b2012-05-12 16:11:50 -03002367 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002368 struct hci_cp_remote_name_req cp;
2369 memset(&cp, 0, sizeof(cp));
2370 bacpy(&cp.bdaddr, &conn->dst);
2371 cp.pscan_rep_mode = 0x02;
2372 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002373 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2374 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002375 conn->dst_type, 0, NULL, 0,
2376 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002377
Johan Hedberg127178d2010-11-18 22:22:29 +02002378 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002379 conn->state = BT_CONNECTED;
2380 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002381 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002382 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002383
Johan Hedbergccd556f2010-11-10 17:11:51 +02002384unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002385 hci_dev_unlock(hdev);
2386}
2387
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002388static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002389{
2390 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002391 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002392 __u16 opcode;
2393
2394 skb_pull(skb, sizeof(*ev));
2395
2396 opcode = __le16_to_cpu(ev->opcode);
2397
2398 switch (opcode) {
2399 case HCI_OP_INQUIRY_CANCEL:
2400 hci_cc_inquiry_cancel(hdev, skb);
2401 break;
2402
Andre Guedes4d934832012-03-21 00:03:35 -03002403 case HCI_OP_PERIODIC_INQ:
2404 hci_cc_periodic_inq(hdev, skb);
2405 break;
2406
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002407 case HCI_OP_EXIT_PERIODIC_INQ:
2408 hci_cc_exit_periodic_inq(hdev, skb);
2409 break;
2410
2411 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2412 hci_cc_remote_name_req_cancel(hdev, skb);
2413 break;
2414
2415 case HCI_OP_ROLE_DISCOVERY:
2416 hci_cc_role_discovery(hdev, skb);
2417 break;
2418
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002419 case HCI_OP_READ_LINK_POLICY:
2420 hci_cc_read_link_policy(hdev, skb);
2421 break;
2422
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002423 case HCI_OP_WRITE_LINK_POLICY:
2424 hci_cc_write_link_policy(hdev, skb);
2425 break;
2426
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002427 case HCI_OP_READ_DEF_LINK_POLICY:
2428 hci_cc_read_def_link_policy(hdev, skb);
2429 break;
2430
2431 case HCI_OP_WRITE_DEF_LINK_POLICY:
2432 hci_cc_write_def_link_policy(hdev, skb);
2433 break;
2434
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002435 case HCI_OP_RESET:
2436 hci_cc_reset(hdev, skb);
2437 break;
2438
2439 case HCI_OP_WRITE_LOCAL_NAME:
2440 hci_cc_write_local_name(hdev, skb);
2441 break;
2442
2443 case HCI_OP_READ_LOCAL_NAME:
2444 hci_cc_read_local_name(hdev, skb);
2445 break;
2446
2447 case HCI_OP_WRITE_AUTH_ENABLE:
2448 hci_cc_write_auth_enable(hdev, skb);
2449 break;
2450
2451 case HCI_OP_WRITE_ENCRYPT_MODE:
2452 hci_cc_write_encrypt_mode(hdev, skb);
2453 break;
2454
2455 case HCI_OP_WRITE_SCAN_ENABLE:
2456 hci_cc_write_scan_enable(hdev, skb);
2457 break;
2458
2459 case HCI_OP_READ_CLASS_OF_DEV:
2460 hci_cc_read_class_of_dev(hdev, skb);
2461 break;
2462
2463 case HCI_OP_WRITE_CLASS_OF_DEV:
2464 hci_cc_write_class_of_dev(hdev, skb);
2465 break;
2466
2467 case HCI_OP_READ_VOICE_SETTING:
2468 hci_cc_read_voice_setting(hdev, skb);
2469 break;
2470
2471 case HCI_OP_WRITE_VOICE_SETTING:
2472 hci_cc_write_voice_setting(hdev, skb);
2473 break;
2474
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002475 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2476 hci_cc_read_num_supported_iac(hdev, skb);
2477 break;
2478
Marcel Holtmann333140b2008-07-14 20:13:48 +02002479 case HCI_OP_WRITE_SSP_MODE:
2480 hci_cc_write_ssp_mode(hdev, skb);
2481 break;
2482
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08002483 case HCI_OP_WRITE_SC_SUPPORT:
2484 hci_cc_write_sc_support(hdev, skb);
2485 break;
2486
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002487 case HCI_OP_READ_LOCAL_VERSION:
2488 hci_cc_read_local_version(hdev, skb);
2489 break;
2490
2491 case HCI_OP_READ_LOCAL_COMMANDS:
2492 hci_cc_read_local_commands(hdev, skb);
2493 break;
2494
2495 case HCI_OP_READ_LOCAL_FEATURES:
2496 hci_cc_read_local_features(hdev, skb);
2497 break;
2498
Andre Guedes971e3a42011-06-30 19:20:52 -03002499 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2500 hci_cc_read_local_ext_features(hdev, skb);
2501 break;
2502
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002503 case HCI_OP_READ_BUFFER_SIZE:
2504 hci_cc_read_buffer_size(hdev, skb);
2505 break;
2506
2507 case HCI_OP_READ_BD_ADDR:
2508 hci_cc_read_bd_addr(hdev, skb);
2509 break;
2510
Johan Hedbergf332ec62013-03-15 17:07:11 -05002511 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2512 hci_cc_read_page_scan_activity(hdev, skb);
2513 break;
2514
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002515 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2516 hci_cc_write_page_scan_activity(hdev, skb);
2517 break;
2518
Johan Hedbergf332ec62013-03-15 17:07:11 -05002519 case HCI_OP_READ_PAGE_SCAN_TYPE:
2520 hci_cc_read_page_scan_type(hdev, skb);
2521 break;
2522
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002523 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2524 hci_cc_write_page_scan_type(hdev, skb);
2525 break;
2526
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002527 case HCI_OP_READ_DATA_BLOCK_SIZE:
2528 hci_cc_read_data_block_size(hdev, skb);
2529 break;
2530
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002531 case HCI_OP_READ_FLOW_CONTROL_MODE:
2532 hci_cc_read_flow_control_mode(hdev, skb);
2533 break;
2534
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002535 case HCI_OP_READ_LOCAL_AMP_INFO:
2536 hci_cc_read_local_amp_info(hdev, skb);
2537 break;
2538
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002539 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2540 hci_cc_read_local_amp_assoc(hdev, skb);
2541 break;
2542
Johan Hedbergd5859e22011-01-25 01:19:58 +02002543 case HCI_OP_READ_INQ_RSP_TX_POWER:
2544 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2545 break;
2546
Johan Hedberg980e1a52011-01-22 06:10:07 +02002547 case HCI_OP_PIN_CODE_REPLY:
2548 hci_cc_pin_code_reply(hdev, skb);
2549 break;
2550
2551 case HCI_OP_PIN_CODE_NEG_REPLY:
2552 hci_cc_pin_code_neg_reply(hdev, skb);
2553 break;
2554
Szymon Jancc35938b2011-03-22 13:12:21 +01002555 case HCI_OP_READ_LOCAL_OOB_DATA:
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08002556 hci_cc_read_local_oob_data(hdev, skb);
2557 break;
2558
2559 case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
2560 hci_cc_read_local_oob_ext_data(hdev, skb);
Szymon Jancc35938b2011-03-22 13:12:21 +01002561 break;
2562
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002563 case HCI_OP_LE_READ_BUFFER_SIZE:
2564 hci_cc_le_read_buffer_size(hdev, skb);
2565 break;
2566
Johan Hedberg60e77322013-01-22 14:01:59 +02002567 case HCI_OP_LE_READ_LOCAL_FEATURES:
2568 hci_cc_le_read_local_features(hdev, skb);
2569 break;
2570
Johan Hedberg8fa19092012-10-19 20:57:49 +03002571 case HCI_OP_LE_READ_ADV_TX_POWER:
2572 hci_cc_le_read_adv_tx_power(hdev, skb);
2573 break;
2574
Johan Hedberga5c29682011-02-19 12:05:57 -03002575 case HCI_OP_USER_CONFIRM_REPLY:
2576 hci_cc_user_confirm_reply(hdev, skb);
2577 break;
2578
2579 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2580 hci_cc_user_confirm_neg_reply(hdev, skb);
2581 break;
2582
Brian Gix1143d452011-11-23 08:28:34 -08002583 case HCI_OP_USER_PASSKEY_REPLY:
2584 hci_cc_user_passkey_reply(hdev, skb);
2585 break;
2586
2587 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2588 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002589 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002590
Marcel Holtmann7a4cd512014-02-19 19:52:13 -08002591 case HCI_OP_LE_SET_RANDOM_ADDR:
2592 hci_cc_le_set_random_addr(hdev, skb);
2593 break;
2594
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002595 case HCI_OP_LE_SET_ADV_ENABLE:
2596 hci_cc_le_set_adv_enable(hdev, skb);
2597 break;
2598
Marcel Holtmann533553f2014-03-21 12:18:10 -07002599 case HCI_OP_LE_SET_SCAN_PARAM:
2600 hci_cc_le_set_scan_param(hdev, skb);
2601 break;
2602
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002603 case HCI_OP_LE_SET_SCAN_ENABLE:
2604 hci_cc_le_set_scan_enable(hdev, skb);
2605 break;
2606
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002607 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2608 hci_cc_le_read_white_list_size(hdev, skb);
2609 break;
2610
Marcel Holtmann0f36b582014-02-27 20:37:31 -08002611 case HCI_OP_LE_CLEAR_WHITE_LIST:
2612 hci_cc_le_clear_white_list(hdev, skb);
2613 break;
2614
2615 case HCI_OP_LE_ADD_TO_WHITE_LIST:
2616 hci_cc_le_add_to_white_list(hdev, skb);
2617 break;
2618
2619 case HCI_OP_LE_DEL_FROM_WHITE_LIST:
2620 hci_cc_le_del_from_white_list(hdev, skb);
2621 break;
2622
Johan Hedberg9b008c02013-01-22 14:02:01 +02002623 case HCI_OP_LE_READ_SUPPORTED_STATES:
2624 hci_cc_le_read_supported_states(hdev, skb);
2625 break;
2626
Andre Guedesf9b49302011-06-30 19:20:53 -03002627 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2628 hci_cc_write_le_host_supported(hdev, skb);
2629 break;
2630
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02002631 case HCI_OP_LE_SET_ADV_PARAM:
2632 hci_cc_set_adv_param(hdev, skb);
2633 break;
2634
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002635 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2636 hci_cc_write_remote_amp_assoc(hdev, skb);
2637 break;
2638
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002639 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002640 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002641 break;
2642 }
2643
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002644 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002645 del_timer(&hdev->cmd_timer);
2646
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002647 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002648
Szymon Jancdbccd792012-12-11 08:51:19 +01002649 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002650 atomic_set(&hdev->cmd_cnt, 1);
2651 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002652 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002653 }
2654}
2655
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002656static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002657{
2658 struct hci_ev_cmd_status *ev = (void *) skb->data;
2659 __u16 opcode;
2660
2661 skb_pull(skb, sizeof(*ev));
2662
2663 opcode = __le16_to_cpu(ev->opcode);
2664
2665 switch (opcode) {
2666 case HCI_OP_INQUIRY:
2667 hci_cs_inquiry(hdev, ev->status);
2668 break;
2669
2670 case HCI_OP_CREATE_CONN:
2671 hci_cs_create_conn(hdev, ev->status);
2672 break;
2673
2674 case HCI_OP_ADD_SCO:
2675 hci_cs_add_sco(hdev, ev->status);
2676 break;
2677
Marcel Holtmannf8558552008-07-14 20:13:49 +02002678 case HCI_OP_AUTH_REQUESTED:
2679 hci_cs_auth_requested(hdev, ev->status);
2680 break;
2681
2682 case HCI_OP_SET_CONN_ENCRYPT:
2683 hci_cs_set_conn_encrypt(hdev, ev->status);
2684 break;
2685
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002686 case HCI_OP_REMOTE_NAME_REQ:
2687 hci_cs_remote_name_req(hdev, ev->status);
2688 break;
2689
Marcel Holtmann769be972008-07-14 20:13:49 +02002690 case HCI_OP_READ_REMOTE_FEATURES:
2691 hci_cs_read_remote_features(hdev, ev->status);
2692 break;
2693
2694 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2695 hci_cs_read_remote_ext_features(hdev, ev->status);
2696 break;
2697
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002698 case HCI_OP_SETUP_SYNC_CONN:
2699 hci_cs_setup_sync_conn(hdev, ev->status);
2700 break;
2701
2702 case HCI_OP_SNIFF_MODE:
2703 hci_cs_sniff_mode(hdev, ev->status);
2704 break;
2705
2706 case HCI_OP_EXIT_SNIFF_MODE:
2707 hci_cs_exit_sniff_mode(hdev, ev->status);
2708 break;
2709
Johan Hedberg8962ee72011-01-20 12:40:27 +02002710 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002711 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002712 break;
2713
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002714 case HCI_OP_CREATE_PHY_LINK:
2715 hci_cs_create_phylink(hdev, ev->status);
2716 break;
2717
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002718 case HCI_OP_ACCEPT_PHY_LINK:
2719 hci_cs_accept_phylink(hdev, ev->status);
2720 break;
2721
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02002722 case HCI_OP_LE_CREATE_CONN:
2723 hci_cs_le_create_conn(hdev, ev->status);
2724 break;
2725
Johan Hedberg81d0c8a2014-03-24 14:39:04 +02002726 case HCI_OP_LE_START_ENC:
2727 hci_cs_le_start_enc(hdev, ev->status);
2728 break;
2729
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002730 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002731 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002732 break;
2733 }
2734
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002735 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002736 del_timer(&hdev->cmd_timer);
2737
Johan Hedberg02350a72013-04-03 21:50:29 +03002738 if (ev->status ||
2739 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2740 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002741
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002742 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002743 atomic_set(&hdev->cmd_cnt, 1);
2744 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002745 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002746 }
2747}
2748
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002749static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002750{
2751 struct hci_ev_role_change *ev = (void *) skb->data;
2752 struct hci_conn *conn;
2753
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002754 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002755
2756 hci_dev_lock(hdev);
2757
2758 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2759 if (conn) {
2760 if (!ev->status) {
2761 if (ev->role)
2762 conn->link_mode &= ~HCI_LM_MASTER;
2763 else
2764 conn->link_mode |= HCI_LM_MASTER;
2765 }
2766
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002767 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002768
2769 hci_role_switch_cfm(conn, ev->status, ev->role);
2770 }
2771
2772 hci_dev_unlock(hdev);
2773}
2774
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002775static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002776{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002777 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002778 int i;
2779
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002780 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2781 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2782 return;
2783 }
2784
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002785 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002786 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002787 BT_DBG("%s bad parameters", hdev->name);
2788 return;
2789 }
2790
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002791 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2792
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002793 for (i = 0; i < ev->num_hndl; i++) {
2794 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795 struct hci_conn *conn;
2796 __u16 handle, count;
2797
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002798 handle = __le16_to_cpu(info->handle);
2799 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002800
2801 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002802 if (!conn)
2803 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002804
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002805 conn->sent -= count;
2806
2807 switch (conn->type) {
2808 case ACL_LINK:
2809 hdev->acl_cnt += count;
2810 if (hdev->acl_cnt > hdev->acl_pkts)
2811 hdev->acl_cnt = hdev->acl_pkts;
2812 break;
2813
2814 case LE_LINK:
2815 if (hdev->le_pkts) {
2816 hdev->le_cnt += count;
2817 if (hdev->le_cnt > hdev->le_pkts)
2818 hdev->le_cnt = hdev->le_pkts;
2819 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002820 hdev->acl_cnt += count;
2821 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002822 hdev->acl_cnt = hdev->acl_pkts;
2823 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002824 break;
2825
2826 case SCO_LINK:
2827 hdev->sco_cnt += count;
2828 if (hdev->sco_cnt > hdev->sco_pkts)
2829 hdev->sco_cnt = hdev->sco_pkts;
2830 break;
2831
2832 default:
2833 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2834 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002835 }
2836 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002837
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002838 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002839}
2840
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002841static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2842 __u16 handle)
2843{
2844 struct hci_chan *chan;
2845
2846 switch (hdev->dev_type) {
2847 case HCI_BREDR:
2848 return hci_conn_hash_lookup_handle(hdev, handle);
2849 case HCI_AMP:
2850 chan = hci_chan_lookup_handle(hdev, handle);
2851 if (chan)
2852 return chan->conn;
2853 break;
2854 default:
2855 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2856 break;
2857 }
2858
2859 return NULL;
2860}
2861
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002862static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002863{
2864 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2865 int i;
2866
2867 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2868 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2869 return;
2870 }
2871
2872 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002873 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002874 BT_DBG("%s bad parameters", hdev->name);
2875 return;
2876 }
2877
2878 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002879 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002880
2881 for (i = 0; i < ev->num_hndl; i++) {
2882 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002883 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002884 __u16 handle, block_count;
2885
2886 handle = __le16_to_cpu(info->handle);
2887 block_count = __le16_to_cpu(info->blocks);
2888
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002889 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002890 if (!conn)
2891 continue;
2892
2893 conn->sent -= block_count;
2894
2895 switch (conn->type) {
2896 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002897 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002898 hdev->block_cnt += block_count;
2899 if (hdev->block_cnt > hdev->num_blocks)
2900 hdev->block_cnt = hdev->num_blocks;
2901 break;
2902
2903 default:
2904 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2905 break;
2906 }
2907 }
2908
2909 queue_work(hdev->workqueue, &hdev->tx_work);
2910}
2911
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002912static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002914 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002915 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002917 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918
2919 hci_dev_lock(hdev);
2920
Marcel Holtmann04837f62006-07-03 10:02:33 +02002921 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2922 if (conn) {
2923 conn->mode = ev->mode;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002924
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002925 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2926 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002927 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002928 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002929 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002930 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002931 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002932
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002933 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002934 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002935 }
2936
2937 hci_dev_unlock(hdev);
2938}
2939
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002940static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002942 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2943 struct hci_conn *conn;
2944
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002945 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002946
2947 hci_dev_lock(hdev);
2948
2949 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002950 if (!conn)
2951 goto unlock;
2952
2953 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002954 hci_conn_hold(conn);
2955 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002956 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002957 }
2958
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002959 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002960 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002961 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002962 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002963 u8 secure;
2964
2965 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2966 secure = 1;
2967 else
2968 secure = 0;
2969
Johan Hedberg744cf192011-11-08 20:40:14 +02002970 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002971 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002972
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002973unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002974 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975}
2976
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002977static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002979 struct hci_ev_link_key_req *ev = (void *) skb->data;
2980 struct hci_cp_link_key_reply cp;
2981 struct hci_conn *conn;
2982 struct link_key *key;
2983
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002984 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002985
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002986 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002987 return;
2988
2989 hci_dev_lock(hdev);
2990
2991 key = hci_find_link_key(hdev, &ev->bdaddr);
2992 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002993 BT_DBG("%s link key not found for %pMR", hdev->name,
2994 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002995 goto not_found;
2996 }
2997
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002998 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2999 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003000
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003001 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003002 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003003 BT_DBG("%s ignoring debug key", hdev->name);
3004 goto not_found;
3005 }
3006
3007 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003008 if (conn) {
Marcel Holtmann66138ce2014-01-10 02:07:20 -08003009 if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
3010 key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003011 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003012 BT_DBG("%s ignoring unauthenticated key", hdev->name);
3013 goto not_found;
3014 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003015
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003016 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003017 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003018 BT_DBG("%s ignoring key unauthenticated for high security",
3019 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003020 goto not_found;
3021 }
3022
3023 conn->key_type = key->type;
3024 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003025 }
3026
3027 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03003028 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003029
3030 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
3031
3032 hci_dev_unlock(hdev);
3033
3034 return;
3035
3036not_found:
3037 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
3038 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003039}
3040
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003041static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003042{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003043 struct hci_ev_link_key_notify *ev = (void *) skb->data;
3044 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003045 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003046
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003047 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003048
3049 hci_dev_lock(hdev);
3050
3051 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3052 if (conn) {
3053 hci_conn_hold(conn);
3054 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02003055 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02003056
3057 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
3058 conn->key_type = ev->key_type;
3059
David Herrmann76a68ba2013-04-06 20:28:37 +02003060 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003061 }
3062
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03003063 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07003064 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003065 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003066
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003067 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003068}
3069
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003070static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02003071{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003072 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02003073 struct hci_conn *conn;
3074
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003075 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02003076
3077 hci_dev_lock(hdev);
3078
3079 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003080 if (conn && !ev->status) {
3081 struct inquiry_entry *ie;
3082
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003083 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3084 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003085 ie->data.clock_offset = ev->clock_offset;
3086 ie->timestamp = jiffies;
3087 }
3088 }
3089
3090 hci_dev_unlock(hdev);
3091}
3092
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003093static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02003094{
3095 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
3096 struct hci_conn *conn;
3097
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003098 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02003099
3100 hci_dev_lock(hdev);
3101
3102 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3103 if (conn && !ev->status)
3104 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
3105
3106 hci_dev_unlock(hdev);
3107}
3108
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003109static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003110{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003111 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003112 struct inquiry_entry *ie;
3113
3114 BT_DBG("%s", hdev->name);
3115
3116 hci_dev_lock(hdev);
3117
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003118 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3119 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003120 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
3121 ie->timestamp = jiffies;
3122 }
3123
3124 hci_dev_unlock(hdev);
3125}
3126
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003127static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
3128 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003129{
3130 struct inquiry_data data;
3131 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003132 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003133
3134 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3135
3136 if (!num_rsp)
3137 return;
3138
Andre Guedes1519cc12012-03-21 00:03:38 -03003139 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3140 return;
3141
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003142 hci_dev_lock(hdev);
3143
3144 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01003145 struct inquiry_info_with_rssi_and_pscan_mode *info;
3146 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003147
Johan Hedberge17acd42011-03-30 23:57:16 +03003148 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003149 bacpy(&data.bdaddr, &info->bdaddr);
3150 data.pscan_rep_mode = info->pscan_rep_mode;
3151 data.pscan_period_mode = info->pscan_period_mode;
3152 data.pscan_mode = info->pscan_mode;
3153 memcpy(data.dev_class, info->dev_class, 3);
3154 data.clock_offset = info->clock_offset;
3155 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003156 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003157
3158 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003159 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003160 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003161 info->dev_class, info->rssi,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02003162 !name_known, ssp, NULL, 0, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003163 }
3164 } else {
3165 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
3166
Johan Hedberge17acd42011-03-30 23:57:16 +03003167 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003168 bacpy(&data.bdaddr, &info->bdaddr);
3169 data.pscan_rep_mode = info->pscan_rep_mode;
3170 data.pscan_period_mode = info->pscan_period_mode;
3171 data.pscan_mode = 0x00;
3172 memcpy(data.dev_class, info->dev_class, 3);
3173 data.clock_offset = info->clock_offset;
3174 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003175 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003176 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003177 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003178 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003179 info->dev_class, info->rssi,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02003180 !name_known, ssp, NULL, 0, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003181 }
3182 }
3183
3184 hci_dev_unlock(hdev);
3185}
3186
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003187static void hci_remote_ext_features_evt(struct hci_dev *hdev,
3188 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003189{
Marcel Holtmann41a96212008-07-14 20:13:48 +02003190 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
3191 struct hci_conn *conn;
3192
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003193 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003194
Marcel Holtmann41a96212008-07-14 20:13:48 +02003195 hci_dev_lock(hdev);
3196
3197 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02003198 if (!conn)
3199 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003200
Johan Hedbergcad718e2013-04-17 15:00:51 +03003201 if (ev->page < HCI_MAX_PAGES)
3202 memcpy(conn->features[ev->page], ev->features, 8);
3203
Johan Hedbergccd556f2010-11-10 17:11:51 +02003204 if (!ev->status && ev->page == 0x01) {
3205 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003206
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003207 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3208 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003209 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02003210
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303211 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02003212 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303213 } else {
3214 /* It is mandatory by the Bluetooth specification that
3215 * Extended Inquiry Results are only used when Secure
3216 * Simple Pairing is enabled, but some devices violate
3217 * this.
3218 *
3219 * To make these devices work, the internal SSP
3220 * enabled flag needs to be cleared if the remote host
3221 * features do not indicate SSP support */
3222 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
3223 }
Marcel Holtmanneb9a8f32014-01-15 22:37:38 -08003224
3225 if (ev->features[0] & LMP_HOST_SC)
3226 set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003227 }
3228
Johan Hedbergccd556f2010-11-10 17:11:51 +02003229 if (conn->state != BT_CONFIG)
3230 goto unlock;
3231
Johan Hedberg671267b2012-05-12 16:11:50 -03003232 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02003233 struct hci_cp_remote_name_req cp;
3234 memset(&cp, 0, sizeof(cp));
3235 bacpy(&cp.bdaddr, &conn->dst);
3236 cp.pscan_rep_mode = 0x02;
3237 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02003238 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3239 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003240 conn->dst_type, 0, NULL, 0,
3241 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02003242
Johan Hedberg127178d2010-11-18 22:22:29 +02003243 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02003244 conn->state = BT_CONNECTED;
3245 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003246 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02003247 }
3248
3249unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02003250 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003251}
3252
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003253static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3254 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003255{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003256 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3257 struct hci_conn *conn;
3258
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003259 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003260
3261 hci_dev_lock(hdev);
3262
3263 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02003264 if (!conn) {
3265 if (ev->link_type == ESCO_LINK)
3266 goto unlock;
3267
3268 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3269 if (!conn)
3270 goto unlock;
3271
3272 conn->type = SCO_LINK;
3273 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003274
Marcel Holtmann732547f2009-04-19 19:14:14 +02003275 switch (ev->status) {
3276 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003277 conn->handle = __le16_to_cpu(ev->handle);
3278 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003279
3280 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02003281 break;
3282
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02003283 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05003284 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003285 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08003286 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003287 case 0x1f: /* Unspecified error */
Andrew Earl27539bc2014-03-10 10:31:04 +00003288 case 0x20: /* Unsupported LMP Parameter value */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003289 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02003290 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3291 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003292 if (hci_setup_sync(conn, conn->link->handle))
3293 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003294 }
3295 /* fall through */
3296
3297 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003298 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003299 break;
3300 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003301
3302 hci_proto_connect_cfm(conn, ev->status);
3303 if (ev->status)
3304 hci_conn_del(conn);
3305
3306unlock:
3307 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003308}
3309
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07003310static inline size_t eir_get_length(u8 *eir, size_t eir_len)
3311{
3312 size_t parsed = 0;
3313
3314 while (parsed < eir_len) {
3315 u8 field_len = eir[0];
3316
3317 if (field_len == 0)
3318 return parsed;
3319
3320 parsed += field_len + 1;
3321 eir += field_len + 1;
3322 }
3323
3324 return eir_len;
3325}
3326
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003327static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3328 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003329{
3330 struct inquiry_data data;
3331 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3332 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303333 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003334
3335 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3336
3337 if (!num_rsp)
3338 return;
3339
Andre Guedes1519cc12012-03-21 00:03:38 -03003340 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3341 return;
3342
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003343 hci_dev_lock(hdev);
3344
Johan Hedberge17acd42011-03-30 23:57:16 +03003345 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003346 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003347
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003348 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003349 data.pscan_rep_mode = info->pscan_rep_mode;
3350 data.pscan_period_mode = info->pscan_period_mode;
3351 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003352 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003353 data.clock_offset = info->clock_offset;
3354 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003355 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003356
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003357 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003358 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003359 sizeof(info->data),
3360 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003361 else
3362 name_known = true;
3363
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003364 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003365 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303366 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003367 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003368 info->dev_class, info->rssi, !name_known,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02003369 ssp, info->data, eir_len, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003370 }
3371
3372 hci_dev_unlock(hdev);
3373}
3374
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003375static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3376 struct sk_buff *skb)
3377{
3378 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3379 struct hci_conn *conn;
3380
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003381 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003382 __le16_to_cpu(ev->handle));
3383
3384 hci_dev_lock(hdev);
3385
3386 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3387 if (!conn)
3388 goto unlock;
3389
3390 if (!ev->status)
3391 conn->sec_level = conn->pending_sec_level;
3392
3393 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3394
3395 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003396 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003397 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003398 goto unlock;
3399 }
3400
3401 if (conn->state == BT_CONFIG) {
3402 if (!ev->status)
3403 conn->state = BT_CONNECTED;
3404
3405 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003406 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003407 } else {
3408 hci_auth_cfm(conn, ev->status);
3409
3410 hci_conn_hold(conn);
3411 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003412 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003413 }
3414
3415unlock:
3416 hci_dev_unlock(hdev);
3417}
3418
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003419static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003420{
3421 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003422 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3423 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003424 /* If both remote and local IO capabilities allow MITM
3425 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003426 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3427 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3428 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003429 else
Mikel Astizacabae92013-06-28 10:56:28 +02003430 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003431 }
3432
3433 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003434 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3435 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003436 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003437
3438 return conn->auth_type;
3439}
3440
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003441static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003442{
3443 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3444 struct hci_conn *conn;
3445
3446 BT_DBG("%s", hdev->name);
3447
3448 hci_dev_lock(hdev);
3449
3450 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003451 if (!conn)
3452 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003453
Johan Hedberg03b555e2011-01-04 15:40:05 +02003454 hci_conn_hold(conn);
3455
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003456 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003457 goto unlock;
3458
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003459 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003460 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003461 struct hci_cp_io_capability_reply cp;
3462
3463 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303464 /* Change the IO capability from KeyboardDisplay
3465 * to DisplayYesNo as it is not supported by BT spec. */
3466 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003467 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003468 conn->auth_type = hci_get_auth_req(conn);
3469 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003470
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003471 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3472 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003473 cp.oob_data = 0x01;
3474 else
3475 cp.oob_data = 0x00;
3476
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003477 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003478 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003479 } else {
3480 struct hci_cp_io_capability_neg_reply cp;
3481
3482 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003483 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003484
3485 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003486 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003487 }
3488
3489unlock:
3490 hci_dev_unlock(hdev);
3491}
3492
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003493static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003494{
3495 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3496 struct hci_conn *conn;
3497
3498 BT_DBG("%s", hdev->name);
3499
3500 hci_dev_lock(hdev);
3501
3502 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3503 if (!conn)
3504 goto unlock;
3505
Johan Hedberg03b555e2011-01-04 15:40:05 +02003506 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003507 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003508 if (ev->oob_data)
3509 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003510
3511unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003512 hci_dev_unlock(hdev);
3513}
3514
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003515static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3516 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003517{
3518 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003519 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003520 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003521
3522 BT_DBG("%s", hdev->name);
3523
3524 hci_dev_lock(hdev);
3525
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003526 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003527 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003528
Johan Hedberg7a828902011-04-28 11:28:53 -07003529 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3530 if (!conn)
3531 goto unlock;
3532
3533 loc_mitm = (conn->auth_type & 0x01);
3534 rem_mitm = (conn->remote_auth & 0x01);
3535
3536 /* If we require MITM but the remote device can't provide that
3537 * (it has NoInputNoOutput) then reject the confirmation
3538 * request. The only exception is when we're dedicated bonding
3539 * initiators (connect_cfm_cb set) since then we always have the MITM
3540 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003541 if (!conn->connect_cfm_cb && loc_mitm &&
3542 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003543 BT_DBG("Rejecting request: remote device can't provide MITM");
3544 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003545 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003546 goto unlock;
3547 }
3548
3549 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003550 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3551 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003552
3553 /* If we're not the initiators request authorization to
3554 * proceed from user space (mgmt_user_confirm with
3555 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003556 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003557 BT_DBG("Confirming auto-accept as acceptor");
3558 confirm_hint = 1;
3559 goto confirm;
3560 }
3561
Johan Hedberg9f616562011-04-28 11:28:54 -07003562 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003563 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003564
3565 if (hdev->auto_accept_delay > 0) {
3566 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003567 queue_delayed_work(conn->hdev->workqueue,
3568 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003569 goto unlock;
3570 }
3571
Johan Hedberg7a828902011-04-28 11:28:53 -07003572 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003573 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003574 goto unlock;
3575 }
3576
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003577confirm:
Johan Hedberg39adbff2014-03-20 08:18:14 +02003578 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
3579 le32_to_cpu(ev->passkey), confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003580
3581unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003582 hci_dev_unlock(hdev);
3583}
3584
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003585static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3586 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003587{
3588 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3589
3590 BT_DBG("%s", hdev->name);
3591
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003592 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003593 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003594}
3595
Johan Hedberg92a25252012-09-06 18:39:26 +03003596static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3597 struct sk_buff *skb)
3598{
3599 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3600 struct hci_conn *conn;
3601
3602 BT_DBG("%s", hdev->name);
3603
3604 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3605 if (!conn)
3606 return;
3607
3608 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3609 conn->passkey_entered = 0;
3610
3611 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3612 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3613 conn->dst_type, conn->passkey_notify,
3614 conn->passkey_entered);
3615}
3616
3617static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3618{
3619 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3620 struct hci_conn *conn;
3621
3622 BT_DBG("%s", hdev->name);
3623
3624 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3625 if (!conn)
3626 return;
3627
3628 switch (ev->type) {
3629 case HCI_KEYPRESS_STARTED:
3630 conn->passkey_entered = 0;
3631 return;
3632
3633 case HCI_KEYPRESS_ENTERED:
3634 conn->passkey_entered++;
3635 break;
3636
3637 case HCI_KEYPRESS_ERASED:
3638 conn->passkey_entered--;
3639 break;
3640
3641 case HCI_KEYPRESS_CLEARED:
3642 conn->passkey_entered = 0;
3643 break;
3644
3645 case HCI_KEYPRESS_COMPLETED:
3646 return;
3647 }
3648
3649 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3650 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3651 conn->dst_type, conn->passkey_notify,
3652 conn->passkey_entered);
3653}
3654
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003655static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3656 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003657{
3658 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3659 struct hci_conn *conn;
3660
3661 BT_DBG("%s", hdev->name);
3662
3663 hci_dev_lock(hdev);
3664
3665 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003666 if (!conn)
3667 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003668
Johan Hedberg2a611692011-02-19 12:06:00 -03003669 /* To avoid duplicate auth_failed events to user space we check
3670 * the HCI_CONN_AUTH_PEND flag which will be set if we
3671 * initiated the authentication. A traditional auth_complete
3672 * event gets always produced as initiator and is also mapped to
3673 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003674 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003675 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003676 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003677
David Herrmann76a68ba2013-04-06 20:28:37 +02003678 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003679
3680unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003681 hci_dev_unlock(hdev);
3682}
3683
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003684static void hci_remote_host_features_evt(struct hci_dev *hdev,
3685 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003686{
3687 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3688 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003689 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003690
3691 BT_DBG("%s", hdev->name);
3692
3693 hci_dev_lock(hdev);
3694
Johan Hedbergcad718e2013-04-17 15:00:51 +03003695 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3696 if (conn)
3697 memcpy(conn->features[1], ev->features, 8);
3698
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003699 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3700 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003701 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003702
3703 hci_dev_unlock(hdev);
3704}
3705
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003706static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3707 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003708{
3709 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3710 struct oob_data *data;
3711
3712 BT_DBG("%s", hdev->name);
3713
3714 hci_dev_lock(hdev);
3715
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003716 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003717 goto unlock;
3718
Szymon Janc2763eda2011-03-22 13:12:22 +01003719 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3720 if (data) {
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003721 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3722 struct hci_cp_remote_oob_ext_data_reply cp;
Szymon Janc2763eda2011-03-22 13:12:22 +01003723
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003724 bacpy(&cp.bdaddr, &ev->bdaddr);
3725 memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3726 memcpy(cp.randomizer192, data->randomizer192,
3727 sizeof(cp.randomizer192));
3728 memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3729 memcpy(cp.randomizer256, data->randomizer256,
3730 sizeof(cp.randomizer256));
Szymon Janc2763eda2011-03-22 13:12:22 +01003731
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003732 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3733 sizeof(cp), &cp);
3734 } else {
3735 struct hci_cp_remote_oob_data_reply cp;
3736
3737 bacpy(&cp.bdaddr, &ev->bdaddr);
3738 memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3739 memcpy(cp.randomizer, data->randomizer192,
3740 sizeof(cp.randomizer));
3741
3742 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3743 sizeof(cp), &cp);
3744 }
Szymon Janc2763eda2011-03-22 13:12:22 +01003745 } else {
3746 struct hci_cp_remote_oob_data_neg_reply cp;
3747
3748 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003749 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3750 sizeof(cp), &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003751 }
3752
Szymon Jance1ba1f12011-04-06 13:01:59 +02003753unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003754 hci_dev_unlock(hdev);
3755}
3756
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003757static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3758 struct sk_buff *skb)
3759{
3760 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3761 struct hci_conn *hcon, *bredr_hcon;
3762
3763 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3764 ev->status);
3765
3766 hci_dev_lock(hdev);
3767
3768 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3769 if (!hcon) {
3770 hci_dev_unlock(hdev);
3771 return;
3772 }
3773
3774 if (ev->status) {
3775 hci_conn_del(hcon);
3776 hci_dev_unlock(hdev);
3777 return;
3778 }
3779
3780 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3781
3782 hcon->state = BT_CONNECTED;
3783 bacpy(&hcon->dst, &bredr_hcon->dst);
3784
3785 hci_conn_hold(hcon);
3786 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003787 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003788
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003789 hci_conn_add_sysfs(hcon);
3790
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003791 amp_physical_cfm(bredr_hcon, hcon);
3792
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003793 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003794}
3795
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003796static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3797{
3798 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3799 struct hci_conn *hcon;
3800 struct hci_chan *hchan;
3801 struct amp_mgr *mgr;
3802
3803 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3804 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3805 ev->status);
3806
3807 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3808 if (!hcon)
3809 return;
3810
3811 /* Create AMP hchan */
3812 hchan = hci_chan_create(hcon);
3813 if (!hchan)
3814 return;
3815
3816 hchan->handle = le16_to_cpu(ev->handle);
3817
3818 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3819
3820 mgr = hcon->amp_mgr;
3821 if (mgr && mgr->bredr_chan) {
3822 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3823
3824 l2cap_chan_lock(bredr_chan);
3825
3826 bredr_chan->conn->mtu = hdev->block_mtu;
3827 l2cap_logical_cfm(bredr_chan, hchan, 0);
3828 hci_conn_hold(hcon);
3829
3830 l2cap_chan_unlock(bredr_chan);
3831 }
3832}
3833
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003834static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3835 struct sk_buff *skb)
3836{
3837 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3838 struct hci_chan *hchan;
3839
3840 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3841 le16_to_cpu(ev->handle), ev->status);
3842
3843 if (ev->status)
3844 return;
3845
3846 hci_dev_lock(hdev);
3847
3848 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3849 if (!hchan)
3850 goto unlock;
3851
3852 amp_destroy_logical_link(hchan, ev->reason);
3853
3854unlock:
3855 hci_dev_unlock(hdev);
3856}
3857
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003858static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3859 struct sk_buff *skb)
3860{
3861 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3862 struct hci_conn *hcon;
3863
3864 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3865
3866 if (ev->status)
3867 return;
3868
3869 hci_dev_lock(hdev);
3870
3871 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3872 if (hcon) {
3873 hcon->state = BT_CLOSED;
3874 hci_conn_del(hcon);
3875 }
3876
3877 hci_dev_unlock(hdev);
3878}
3879
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003880static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003881{
3882 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3883 struct hci_conn *conn;
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003884 struct smp_irk *irk;
Ville Tervofcd89c02011-02-10 22:38:47 -03003885
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003886 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003887
3888 hci_dev_lock(hdev);
3889
Andre Guedesb47a09b2012-07-27 15:10:15 -03003890 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003891 if (!conn) {
3892 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3893 if (!conn) {
3894 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003895 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003896 }
Andre Guedes29b79882011-05-31 14:20:54 -03003897
3898 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003899
3900 if (ev->role == LE_CONN_ROLE_MASTER) {
3901 conn->out = true;
3902 conn->link_mode |= HCI_LM_MASTER;
3903 }
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02003904
3905 /* If we didn't have a hci_conn object previously
3906 * but we're in master role this must be something
3907 * initiated using a white list. Since white list based
3908 * connections are not "first class citizens" we don't
3909 * have full tracking of them. Therefore, we go ahead
3910 * with a "best effort" approach of determining the
3911 * initiator address based on the HCI_PRIVACY flag.
3912 */
3913 if (conn->out) {
3914 conn->resp_addr_type = ev->bdaddr_type;
3915 bacpy(&conn->resp_addr, &ev->bdaddr);
3916 if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
3917 conn->init_addr_type = ADDR_LE_DEV_RANDOM;
3918 bacpy(&conn->init_addr, &hdev->rpa);
3919 } else {
3920 hci_copy_identity_address(hdev,
3921 &conn->init_addr,
3922 &conn->init_addr_type);
3923 }
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02003924 }
Johan Hedberg9489eca2014-02-28 17:45:46 +02003925 } else {
3926 cancel_delayed_work(&conn->le_conn_timeout);
Ville Tervob62f3282011-02-10 22:38:50 -03003927 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003928
Johan Hedberg80c24ab2014-03-24 20:21:51 +02003929 if (!conn->out) {
3930 /* Set the responder (our side) address type based on
3931 * the advertising address type.
3932 */
3933 conn->resp_addr_type = hdev->adv_addr_type;
3934 if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM)
3935 bacpy(&conn->resp_addr, &hdev->random_addr);
3936 else
3937 bacpy(&conn->resp_addr, &hdev->bdaddr);
3938
3939 conn->init_addr_type = ev->bdaddr_type;
3940 bacpy(&conn->init_addr, &ev->bdaddr);
3941 }
3942
Marcel Holtmannedb4b462014-02-18 15:13:43 -08003943 /* Lookup the identity address from the stored connection
3944 * address and address type.
3945 *
3946 * When establishing connections to an identity address, the
3947 * connection procedure will store the resolvable random
3948 * address first. Now if it can be converted back into the
3949 * identity address, start using the identity address from
3950 * now on.
3951 */
3952 irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003953 if (irk) {
3954 bacpy(&conn->dst, &irk->bdaddr);
3955 conn->dst_type = irk->addr_type;
3956 }
3957
Andre Guedescd17dec2012-07-27 15:10:16 -03003958 if (ev->status) {
Andre Guedes06c053f2014-02-26 20:21:41 -03003959 hci_le_conn_failed(conn, ev->status);
Andre Guedescd17dec2012-07-27 15:10:16 -03003960 goto unlock;
3961 }
3962
Johan Hedbergb644ba32012-01-17 21:48:47 +02003963 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Marcel Holtmann01fdb0f2014-02-18 14:22:19 -08003964 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003965 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003966
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003967 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003968 conn->handle = __le16_to_cpu(ev->handle);
3969 conn->state = BT_CONNECTED;
3970
Jukka Rissanen18722c22013-12-11 17:05:37 +02003971 if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
3972 set_bit(HCI_CONN_6LOWPAN, &conn->flags);
3973
Ville Tervofcd89c02011-02-10 22:38:47 -03003974 hci_conn_add_sysfs(conn);
3975
3976 hci_proto_connect_cfm(conn, ev->status);
3977
Andre Guedesa4790db2014-02-26 20:21:47 -03003978 hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
3979
Ville Tervofcd89c02011-02-10 22:38:47 -03003980unlock:
3981 hci_dev_unlock(hdev);
3982}
3983
Andre Guedesa4790db2014-02-26 20:21:47 -03003984/* This function requires the caller holds hdev->lock */
3985static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
3986 u8 addr_type)
3987{
3988 struct hci_conn *conn;
Andre Guedes5b906a82014-02-26 20:21:53 -03003989 struct smp_irk *irk;
3990
3991 /* If this is a resolvable address, we should resolve it and then
3992 * update address and address type variables.
3993 */
3994 irk = hci_get_irk(hdev, addr, addr_type);
3995 if (irk) {
3996 addr = &irk->bdaddr;
3997 addr_type = irk->addr_type;
3998 }
Andre Guedesa4790db2014-02-26 20:21:47 -03003999
4000 if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
4001 return;
4002
4003 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
4004 HCI_AT_NO_BONDING);
4005 if (!IS_ERR(conn))
4006 return;
4007
4008 switch (PTR_ERR(conn)) {
4009 case -EBUSY:
4010 /* If hci_connect() returns -EBUSY it means there is already
4011 * an LE connection attempt going on. Since controllers don't
4012 * support more than one connection attempt at the time, we
4013 * don't consider this an error case.
4014 */
4015 break;
4016 default:
4017 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
4018 }
4019}
4020
Johan Hedberg4af605d2014-03-24 10:48:00 +02004021static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
4022 u8 bdaddr_type, s8 rssi, u8 *data, u8 len)
4023{
Johan Hedbergb9a63282014-03-25 10:51:52 +02004024 struct discovery_state *d = &hdev->discovery;
Johan Hedberg474ee062014-03-25 14:34:59 +02004025 bool match;
Johan Hedbergb9a63282014-03-25 10:51:52 +02004026
Johan Hedbergca5c4be2014-03-25 10:30:46 +02004027 /* Passive scanning shouldn't trigger any device found events */
4028 if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
4029 if (type == LE_ADV_IND || type == LE_ADV_DIRECT_IND)
4030 check_pending_le_conn(hdev, bdaddr, bdaddr_type);
4031 return;
4032 }
Johan Hedberg4af605d2014-03-24 10:48:00 +02004033
Johan Hedbergb9a63282014-03-25 10:51:52 +02004034 /* If there's nothing pending either store the data from this
4035 * event or send an immediate device found event if the data
4036 * should not be stored for later.
4037 */
4038 if (!has_pending_adv_report(hdev)) {
4039 /* If the report will trigger a SCAN_REQ store it for
4040 * later merging.
4041 */
4042 if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
4043 store_pending_adv_report(hdev, bdaddr, bdaddr_type,
Johan Hedbergff5cd292014-03-25 14:40:52 +02004044 rssi, data, len);
Johan Hedbergb9a63282014-03-25 10:51:52 +02004045 return;
4046 }
4047
4048 mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
4049 rssi, 0, 1, data, len, NULL, 0);
4050 return;
4051 }
4052
Johan Hedberg474ee062014-03-25 14:34:59 +02004053 /* Check if the pending report is for the same device as the new one */
4054 match = (!bacmp(bdaddr, &d->last_adv_addr) &&
4055 bdaddr_type == d->last_adv_addr_type);
4056
Johan Hedbergb9a63282014-03-25 10:51:52 +02004057 /* If the pending data doesn't match this report or this isn't a
4058 * scan response (e.g. we got a duplicate ADV_IND) then force
4059 * sending of the pending data.
4060 */
Johan Hedberg474ee062014-03-25 14:34:59 +02004061 if (type != LE_ADV_SCAN_RSP || !match) {
4062 /* Send out whatever is in the cache, but skip duplicates */
4063 if (!match)
4064 mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
Johan Hedbergff5cd292014-03-25 14:40:52 +02004065 d->last_adv_addr_type, NULL,
4066 d->last_adv_rssi, 0, 1,
4067 d->last_adv_data,
Johan Hedberg474ee062014-03-25 14:34:59 +02004068 d->last_adv_data_len, NULL, 0);
Johan Hedbergb9a63282014-03-25 10:51:52 +02004069
4070 /* If the new report will trigger a SCAN_REQ store it for
4071 * later merging.
4072 */
4073 if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
4074 store_pending_adv_report(hdev, bdaddr, bdaddr_type,
Johan Hedbergff5cd292014-03-25 14:40:52 +02004075 rssi, data, len);
Johan Hedbergb9a63282014-03-25 10:51:52 +02004076 return;
4077 }
4078
4079 /* The advertising reports cannot be merged, so clear
4080 * the pending report and send out a device found event.
4081 */
4082 clear_pending_adv_report(hdev);
4083 mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
4084 d->last_adv_addr_type, NULL, rssi, 0, 1,
4085 data, len, NULL, 0);
4086 return;
4087 }
4088
4089 /* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and
4090 * the new event is a SCAN_RSP. We can therefore proceed with
4091 * sending a merged device found event.
4092 */
4093 mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
4094 d->last_adv_addr_type, NULL, rssi, 0, 1, data, len,
4095 d->last_adv_data, d->last_adv_data_len);
4096 clear_pending_adv_report(hdev);
Johan Hedberg4af605d2014-03-24 10:48:00 +02004097}
4098
Gustavo Padovan6039aa72012-05-23 04:04:18 -03004099static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03004100{
Andre Guedese95beb42011-09-26 20:48:35 -03004101 u8 num_reports = skb->data[0];
4102 void *ptr = &skb->data[1];
Andre Guedes9aa04c92011-05-26 16:23:51 -03004103
Andre Guedesa4790db2014-02-26 20:21:47 -03004104 hci_dev_lock(hdev);
4105
Andre Guedese95beb42011-09-26 20:48:35 -03004106 while (num_reports--) {
4107 struct hci_ev_le_advertising_info *ev = ptr;
Johan Hedberg4af605d2014-03-24 10:48:00 +02004108 s8 rssi;
Andre Guedesa4790db2014-02-26 20:21:47 -03004109
Andre Guedes3c9e9192012-01-10 18:20:50 -03004110 rssi = ev->data[ev->length];
Johan Hedberg4af605d2014-03-24 10:48:00 +02004111 process_adv_report(hdev, ev->evt_type, &ev->bdaddr,
4112 ev->bdaddr_type, rssi, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03004113
Andre Guedese95beb42011-09-26 20:48:35 -03004114 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03004115 }
Andre Guedesa4790db2014-02-26 20:21:47 -03004116
4117 hci_dev_unlock(hdev);
Andre Guedes9aa04c92011-05-26 16:23:51 -03004118}
4119
Gustavo Padovan6039aa72012-05-23 04:04:18 -03004120static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004121{
4122 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
4123 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004124 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004125 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004126 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004127
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004128 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004129
4130 hci_dev_lock(hdev);
4131
4132 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004133 if (conn == NULL)
4134 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004135
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08004136 ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->out);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004137 if (ltk == NULL)
4138 goto not_found;
4139
4140 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004141 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004142
4143 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03004144 conn->pending_sec_level = BT_SECURITY_HIGH;
4145 else
4146 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004147
Andre Guedes89cbb4d2013-07-31 16:25:29 -03004148 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004149
4150 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
4151
Claudio Takahasi5981a882013-07-25 16:34:24 -03004152 /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
4153 * temporary key used to encrypt a connection following
4154 * pairing. It is used during the Encrypted Session Setup to
4155 * distribute the keys. Later, security can be re-established
4156 * using a distributed LTK.
4157 */
4158 if (ltk->type == HCI_SMP_STK_SLAVE) {
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004159 list_del(&ltk->list);
4160 kfree(ltk);
4161 }
4162
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004163 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004164
4165 return;
4166
4167not_found:
4168 neg.handle = ev->handle;
4169 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
4170 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004171}
4172
Gustavo Padovan6039aa72012-05-23 04:04:18 -03004173static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03004174{
4175 struct hci_ev_le_meta *le_ev = (void *) skb->data;
4176
4177 skb_pull(skb, sizeof(*le_ev));
4178
4179 switch (le_ev->subevent) {
4180 case HCI_EV_LE_CONN_COMPLETE:
4181 hci_le_conn_complete_evt(hdev, skb);
4182 break;
4183
Andre Guedes9aa04c92011-05-26 16:23:51 -03004184 case HCI_EV_LE_ADVERTISING_REPORT:
4185 hci_le_adv_report_evt(hdev, skb);
4186 break;
4187
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004188 case HCI_EV_LE_LTK_REQ:
4189 hci_le_ltk_request_evt(hdev, skb);
4190 break;
4191
Ville Tervofcd89c02011-02-10 22:38:47 -03004192 default:
4193 break;
4194 }
4195}
4196
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004197static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
4198{
4199 struct hci_ev_channel_selected *ev = (void *) skb->data;
4200 struct hci_conn *hcon;
4201
4202 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
4203
4204 skb_pull(skb, sizeof(*ev));
4205
4206 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
4207 if (!hcon)
4208 return;
4209
4210 amp_read_loc_assoc_final_data(hdev, hcon);
4211}
4212
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
4214{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004215 struct hci_event_hdr *hdr = (void *) skb->data;
4216 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004217
Johan Hedbergb6ddb632013-04-02 13:34:31 +03004218 hci_dev_lock(hdev);
4219
4220 /* Received events are (currently) only needed when a request is
4221 * ongoing so avoid unnecessary memory allocation.
4222 */
4223 if (hdev->req_status == HCI_REQ_PEND) {
4224 kfree_skb(hdev->recv_evt);
4225 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
4226 }
4227
4228 hci_dev_unlock(hdev);
4229
Linus Torvalds1da177e2005-04-16 15:20:36 -07004230 skb_pull(skb, HCI_EVENT_HDR_SIZE);
4231
Johan Hedberg02350a72013-04-03 21:50:29 +03004232 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02004233 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
4234 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03004235
4236 hci_req_cmd_complete(hdev, opcode, 0);
4237 }
4238
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004239 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240 case HCI_EV_INQUIRY_COMPLETE:
4241 hci_inquiry_complete_evt(hdev, skb);
4242 break;
4243
4244 case HCI_EV_INQUIRY_RESULT:
4245 hci_inquiry_result_evt(hdev, skb);
4246 break;
4247
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004248 case HCI_EV_CONN_COMPLETE:
4249 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02004250 break;
4251
Linus Torvalds1da177e2005-04-16 15:20:36 -07004252 case HCI_EV_CONN_REQUEST:
4253 hci_conn_request_evt(hdev, skb);
4254 break;
4255
Linus Torvalds1da177e2005-04-16 15:20:36 -07004256 case HCI_EV_DISCONN_COMPLETE:
4257 hci_disconn_complete_evt(hdev, skb);
4258 break;
4259
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260 case HCI_EV_AUTH_COMPLETE:
4261 hci_auth_complete_evt(hdev, skb);
4262 break;
4263
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004264 case HCI_EV_REMOTE_NAME:
4265 hci_remote_name_evt(hdev, skb);
4266 break;
4267
Linus Torvalds1da177e2005-04-16 15:20:36 -07004268 case HCI_EV_ENCRYPT_CHANGE:
4269 hci_encrypt_change_evt(hdev, skb);
4270 break;
4271
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004272 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
4273 hci_change_link_key_complete_evt(hdev, skb);
4274 break;
4275
4276 case HCI_EV_REMOTE_FEATURES:
4277 hci_remote_features_evt(hdev, skb);
4278 break;
4279
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004280 case HCI_EV_CMD_COMPLETE:
4281 hci_cmd_complete_evt(hdev, skb);
4282 break;
4283
4284 case HCI_EV_CMD_STATUS:
4285 hci_cmd_status_evt(hdev, skb);
4286 break;
4287
4288 case HCI_EV_ROLE_CHANGE:
4289 hci_role_change_evt(hdev, skb);
4290 break;
4291
4292 case HCI_EV_NUM_COMP_PKTS:
4293 hci_num_comp_pkts_evt(hdev, skb);
4294 break;
4295
4296 case HCI_EV_MODE_CHANGE:
4297 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004298 break;
4299
4300 case HCI_EV_PIN_CODE_REQ:
4301 hci_pin_code_request_evt(hdev, skb);
4302 break;
4303
4304 case HCI_EV_LINK_KEY_REQ:
4305 hci_link_key_request_evt(hdev, skb);
4306 break;
4307
4308 case HCI_EV_LINK_KEY_NOTIFY:
4309 hci_link_key_notify_evt(hdev, skb);
4310 break;
4311
4312 case HCI_EV_CLOCK_OFFSET:
4313 hci_clock_offset_evt(hdev, skb);
4314 break;
4315
Marcel Holtmanna8746412008-07-14 20:13:46 +02004316 case HCI_EV_PKT_TYPE_CHANGE:
4317 hci_pkt_type_change_evt(hdev, skb);
4318 break;
4319
Marcel Holtmann85a1e932005-08-09 20:28:02 -07004320 case HCI_EV_PSCAN_REP_MODE:
4321 hci_pscan_rep_mode_evt(hdev, skb);
4322 break;
4323
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004324 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
4325 hci_inquiry_result_with_rssi_evt(hdev, skb);
4326 break;
4327
4328 case HCI_EV_REMOTE_EXT_FEATURES:
4329 hci_remote_ext_features_evt(hdev, skb);
4330 break;
4331
4332 case HCI_EV_SYNC_CONN_COMPLETE:
4333 hci_sync_conn_complete_evt(hdev, skb);
4334 break;
4335
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004336 case HCI_EV_EXTENDED_INQUIRY_RESULT:
4337 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004338 break;
4339
Johan Hedberg1c2e0042012-06-08 23:31:13 +08004340 case HCI_EV_KEY_REFRESH_COMPLETE:
4341 hci_key_refresh_complete_evt(hdev, skb);
4342 break;
4343
Marcel Holtmann04936842008-07-14 20:13:48 +02004344 case HCI_EV_IO_CAPA_REQUEST:
4345 hci_io_capa_request_evt(hdev, skb);
4346 break;
4347
Johan Hedberg03b555e2011-01-04 15:40:05 +02004348 case HCI_EV_IO_CAPA_REPLY:
4349 hci_io_capa_reply_evt(hdev, skb);
4350 break;
4351
Johan Hedberga5c29682011-02-19 12:05:57 -03004352 case HCI_EV_USER_CONFIRM_REQUEST:
4353 hci_user_confirm_request_evt(hdev, skb);
4354 break;
4355
Brian Gix1143d452011-11-23 08:28:34 -08004356 case HCI_EV_USER_PASSKEY_REQUEST:
4357 hci_user_passkey_request_evt(hdev, skb);
4358 break;
4359
Johan Hedberg92a25252012-09-06 18:39:26 +03004360 case HCI_EV_USER_PASSKEY_NOTIFY:
4361 hci_user_passkey_notify_evt(hdev, skb);
4362 break;
4363
4364 case HCI_EV_KEYPRESS_NOTIFY:
4365 hci_keypress_notify_evt(hdev, skb);
4366 break;
4367
Marcel Holtmann04936842008-07-14 20:13:48 +02004368 case HCI_EV_SIMPLE_PAIR_COMPLETE:
4369 hci_simple_pair_complete_evt(hdev, skb);
4370 break;
4371
Marcel Holtmann41a96212008-07-14 20:13:48 +02004372 case HCI_EV_REMOTE_HOST_FEATURES:
4373 hci_remote_host_features_evt(hdev, skb);
4374 break;
4375
Ville Tervofcd89c02011-02-10 22:38:47 -03004376 case HCI_EV_LE_META:
4377 hci_le_meta_evt(hdev, skb);
4378 break;
4379
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004380 case HCI_EV_CHANNEL_SELECTED:
4381 hci_chan_selected_evt(hdev, skb);
4382 break;
4383
Szymon Janc2763eda2011-03-22 13:12:22 +01004384 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
4385 hci_remote_oob_data_request_evt(hdev, skb);
4386 break;
4387
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03004388 case HCI_EV_PHY_LINK_COMPLETE:
4389 hci_phy_link_complete_evt(hdev, skb);
4390 break;
4391
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004392 case HCI_EV_LOGICAL_LINK_COMPLETE:
4393 hci_loglink_complete_evt(hdev, skb);
4394 break;
4395
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02004396 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
4397 hci_disconn_loglink_complete_evt(hdev, skb);
4398 break;
4399
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02004400 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
4401 hci_disconn_phylink_complete_evt(hdev, skb);
4402 break;
4403
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02004404 case HCI_EV_NUM_COMP_BLOCKS:
4405 hci_num_comp_blocks_evt(hdev, skb);
4406 break;
4407
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004408 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004409 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004410 break;
4411 }
4412
4413 kfree_skb(skb);
4414 hdev->stat.evt_rx++;
4415}