blob: fa614e3430a73329b83edc61ebc8490f8f6d1324 [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,
Johan Hedbergab0aa432014-03-26 14:17:12 +02001094 d->last_adv_addr_type, NULL,
1095 d->last_adv_rssi, 0, 1,
1096 d->last_adv_data,
Johan Hedbergb9a63282014-03-25 10:51:52 +02001097 d->last_adv_data_len, NULL, 0);
1098 }
1099
Johan Hedberg317ac8c2014-02-28 20:26:12 +02001100 /* Cancel this timer so that we don't try to disable scanning
1101 * when it's already disabled.
1102 */
1103 cancel_delayed_work(&hdev->le_scan_disable);
1104
Andre Guedesd23264a2011-11-25 20:53:38 -03001105 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Johan Hedberg81ad6fd2014-02-28 20:26:13 +02001106 /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
1107 * interrupted scanning due to a connect request. Mark
1108 * therefore discovery as stopped.
1109 */
1110 if (test_and_clear_bit(HCI_LE_SCAN_INTERRUPTED,
1111 &hdev->dev_flags))
1112 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001113 break;
1114
1115 default:
1116 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1117 break;
Andre Guedes35815082011-05-26 16:23:53 -03001118 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001119}
1120
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001121static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1122 struct sk_buff *skb)
1123{
1124 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1125
1126 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1127
1128 if (!rp->status)
1129 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001130}
1131
Marcel Holtmann0f36b582014-02-27 20:37:31 -08001132static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
1133 struct sk_buff *skb)
1134{
1135 __u8 status = *((__u8 *) skb->data);
1136
1137 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1138
1139 if (!status)
1140 hci_white_list_clear(hdev);
1141}
1142
1143static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
1144 struct sk_buff *skb)
1145{
1146 struct hci_cp_le_add_to_white_list *sent;
1147 __u8 status = *((__u8 *) skb->data);
1148
1149 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1150
1151 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST);
1152 if (!sent)
1153 return;
1154
1155 if (!status)
1156 hci_white_list_add(hdev, &sent->bdaddr, sent->bdaddr_type);
1157}
1158
1159static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
1160 struct sk_buff *skb)
1161{
1162 struct hci_cp_le_del_from_white_list *sent;
1163 __u8 status = *((__u8 *) skb->data);
1164
1165 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1166
1167 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST);
1168 if (!sent)
1169 return;
1170
1171 if (!status)
1172 hci_white_list_del(hdev, &sent->bdaddr, sent->bdaddr_type);
1173}
1174
Johan Hedberg9b008c02013-01-22 14:02:01 +02001175static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1176 struct sk_buff *skb)
1177{
1178 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1179
1180 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1181
1182 if (!rp->status)
1183 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001184}
1185
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001186static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1187 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001188{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001189 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001190 __u8 status = *((__u8 *) skb->data);
1191
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001192 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001193
Johan Hedberg06199cf2012-02-22 16:37:11 +02001194 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001195 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001196 return;
1197
Johan Hedberg8f984df2012-02-28 01:07:22 +02001198 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001199 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001200 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001201 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1202 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001203 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001204 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001205 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001206 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001207
1208 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001209 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001210 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001211 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001212 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001213}
1214
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02001215static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
1216{
1217 struct hci_cp_le_set_adv_param *cp;
1218 u8 status = *((u8 *) skb->data);
1219
1220 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1221
1222 if (status)
1223 return;
1224
1225 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
1226 if (!cp)
1227 return;
1228
1229 hci_dev_lock(hdev);
1230 hdev->adv_addr_type = cp->own_address_type;
1231 hci_dev_unlock(hdev);
1232}
1233
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001234static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1235 struct sk_buff *skb)
1236{
1237 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1238
1239 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1240 hdev->name, rp->status, rp->phy_handle);
1241
1242 if (rp->status)
1243 return;
1244
1245 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1246}
1247
Andrzej Kaczmarek5ae76a92014-05-08 15:32:08 +02001248static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb)
1249{
1250 struct hci_rp_read_rssi *rp = (void *) skb->data;
1251 struct hci_conn *conn;
1252
1253 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1254
1255 if (rp->status)
1256 return;
1257
1258 hci_dev_lock(hdev);
1259
1260 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
1261 if (conn)
1262 conn->rssi = rp->rssi;
1263
1264 hci_dev_unlock(hdev);
1265}
1266
Andrzej Kaczmarek5a134fa2014-05-09 21:35:28 +02001267static void hci_cc_read_tx_power(struct hci_dev *hdev, struct sk_buff *skb)
1268{
1269 struct hci_cp_read_tx_power *sent;
1270 struct hci_rp_read_tx_power *rp = (void *) skb->data;
1271 struct hci_conn *conn;
1272
1273 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1274
1275 if (rp->status)
1276 return;
1277
1278 sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER);
1279 if (!sent)
1280 return;
1281
1282 hci_dev_lock(hdev);
1283
1284 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
1285 if (conn && sent->type == 0x00)
1286 conn->tx_power = rp->tx_power;
1287
1288 hci_dev_unlock(hdev);
1289}
1290
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001291static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001292{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001293 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001294
1295 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001296 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001297 return;
1298 }
1299
Andre Guedes89352e72011-11-04 14:16:53 -03001300 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001301}
1302
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001303static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001305 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001308 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001309
1310 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311 if (!cp)
1312 return;
1313
1314 hci_dev_lock(hdev);
1315
1316 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1317
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001318 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319
1320 if (status) {
1321 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001322 if (status != 0x0c || conn->attempt > 2) {
1323 conn->state = BT_CLOSED;
1324 hci_proto_connect_cfm(conn, status);
1325 hci_conn_del(conn);
1326 } else
1327 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 }
1329 } else {
1330 if (!conn) {
1331 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1332 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001333 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 conn->link_mode |= HCI_LM_MASTER;
1335 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001336 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 }
1338 }
1339
1340 hci_dev_unlock(hdev);
1341}
1342
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001343static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001345 struct hci_cp_add_sco *cp;
1346 struct hci_conn *acl, *sco;
1347 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001349 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001350
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001351 if (!status)
1352 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001354 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1355 if (!cp)
1356 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001358 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001360 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001361
1362 hci_dev_lock(hdev);
1363
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001364 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001365 if (acl) {
1366 sco = acl->link;
1367 if (sco) {
1368 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001369
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001370 hci_proto_connect_cfm(sco, status);
1371 hci_conn_del(sco);
1372 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001373 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001374
1375 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376}
1377
Marcel Holtmannf8558552008-07-14 20:13:49 +02001378static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1379{
1380 struct hci_cp_auth_requested *cp;
1381 struct hci_conn *conn;
1382
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001383 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001384
1385 if (!status)
1386 return;
1387
1388 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1389 if (!cp)
1390 return;
1391
1392 hci_dev_lock(hdev);
1393
1394 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1395 if (conn) {
1396 if (conn->state == BT_CONFIG) {
1397 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001398 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001399 }
1400 }
1401
1402 hci_dev_unlock(hdev);
1403}
1404
1405static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1406{
1407 struct hci_cp_set_conn_encrypt *cp;
1408 struct hci_conn *conn;
1409
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001410 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001411
1412 if (!status)
1413 return;
1414
1415 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1416 if (!cp)
1417 return;
1418
1419 hci_dev_lock(hdev);
1420
1421 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1422 if (conn) {
1423 if (conn->state == BT_CONFIG) {
1424 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001425 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001426 }
1427 }
1428
1429 hci_dev_unlock(hdev);
1430}
1431
Johan Hedberg127178d2010-11-18 22:22:29 +02001432static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001433 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001434{
Johan Hedberg392599b2010-11-18 22:22:28 +02001435 if (conn->state != BT_CONFIG || !conn->out)
1436 return 0;
1437
Johan Hedberg765c2a92011-01-19 12:06:52 +05301438 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001439 return 0;
1440
1441 /* Only request authentication for SSP connections or non-SSP
Johan Hedberg264b8b42014-01-08 16:40:39 +02001442 * devices with sec_level MEDIUM or HIGH or if MITM protection
1443 * is requested.
1444 */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001445 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
Johan Hedberg264b8b42014-01-08 16:40:39 +02001446 conn->pending_sec_level != BT_SECURITY_HIGH &&
1447 conn->pending_sec_level != BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001448 return 0;
1449
Johan Hedberg392599b2010-11-18 22:22:28 +02001450 return 1;
1451}
1452
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001453static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001454 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001455{
1456 struct hci_cp_remote_name_req cp;
1457
1458 memset(&cp, 0, sizeof(cp));
1459
1460 bacpy(&cp.bdaddr, &e->data.bdaddr);
1461 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1462 cp.pscan_mode = e->data.pscan_mode;
1463 cp.clock_offset = e->data.clock_offset;
1464
1465 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1466}
1467
Johan Hedbergb644ba32012-01-17 21:48:47 +02001468static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001469{
1470 struct discovery_state *discov = &hdev->discovery;
1471 struct inquiry_entry *e;
1472
Johan Hedbergb644ba32012-01-17 21:48:47 +02001473 if (list_empty(&discov->resolve))
1474 return false;
1475
1476 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001477 if (!e)
1478 return false;
1479
Johan Hedbergb644ba32012-01-17 21:48:47 +02001480 if (hci_resolve_name(hdev, e) == 0) {
1481 e->name_state = NAME_PENDING;
1482 return true;
1483 }
1484
1485 return false;
1486}
1487
1488static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001489 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001490{
1491 struct discovery_state *discov = &hdev->discovery;
1492 struct inquiry_entry *e;
1493
1494 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001495 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1496 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001497
1498 if (discov->state == DISCOVERY_STOPPED)
1499 return;
1500
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001501 if (discov->state == DISCOVERY_STOPPING)
1502 goto discov_complete;
1503
1504 if (discov->state != DISCOVERY_RESOLVING)
1505 return;
1506
1507 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001508 /* If the device was not found in a list of found devices names of which
1509 * are pending. there is no need to continue resolving a next name as it
1510 * will be done upon receiving another Remote Name Request Complete
1511 * Event */
1512 if (!e)
1513 return;
1514
1515 list_del(&e->list);
1516 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001517 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001518 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1519 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001520 } else {
1521 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001522 }
1523
Johan Hedbergb644ba32012-01-17 21:48:47 +02001524 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001525 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001526
1527discov_complete:
1528 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1529}
1530
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001531static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1532{
Johan Hedberg127178d2010-11-18 22:22:29 +02001533 struct hci_cp_remote_name_req *cp;
1534 struct hci_conn *conn;
1535
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001536 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001537
1538 /* If successful wait for the name req complete event before
1539 * checking for the need to do authentication */
1540 if (!status)
1541 return;
1542
1543 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1544 if (!cp)
1545 return;
1546
1547 hci_dev_lock(hdev);
1548
1549 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001550
1551 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1552 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1553
Johan Hedberg79c6c702011-04-28 11:28:55 -07001554 if (!conn)
1555 goto unlock;
1556
1557 if (!hci_outgoing_auth_needed(hdev, conn))
1558 goto unlock;
1559
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001560 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001561 struct hci_cp_auth_requested auth_cp;
1562
1563 auth_cp.handle = __cpu_to_le16(conn->handle);
1564 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1565 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001566 }
1567
Johan Hedberg79c6c702011-04-28 11:28:55 -07001568unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001569 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001570}
1571
Marcel Holtmann769be972008-07-14 20:13:49 +02001572static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1573{
1574 struct hci_cp_read_remote_features *cp;
1575 struct hci_conn *conn;
1576
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001577 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001578
1579 if (!status)
1580 return;
1581
1582 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1583 if (!cp)
1584 return;
1585
1586 hci_dev_lock(hdev);
1587
1588 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1589 if (conn) {
1590 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001591 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001592 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001593 }
1594 }
1595
1596 hci_dev_unlock(hdev);
1597}
1598
1599static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1600{
1601 struct hci_cp_read_remote_ext_features *cp;
1602 struct hci_conn *conn;
1603
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001604 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001605
1606 if (!status)
1607 return;
1608
1609 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1610 if (!cp)
1611 return;
1612
1613 hci_dev_lock(hdev);
1614
1615 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1616 if (conn) {
1617 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001618 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001619 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001620 }
1621 }
1622
1623 hci_dev_unlock(hdev);
1624}
1625
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001626static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1627{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001628 struct hci_cp_setup_sync_conn *cp;
1629 struct hci_conn *acl, *sco;
1630 __u16 handle;
1631
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001632 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001633
1634 if (!status)
1635 return;
1636
1637 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1638 if (!cp)
1639 return;
1640
1641 handle = __le16_to_cpu(cp->handle);
1642
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001643 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001644
1645 hci_dev_lock(hdev);
1646
1647 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001648 if (acl) {
1649 sco = acl->link;
1650 if (sco) {
1651 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001652
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001653 hci_proto_connect_cfm(sco, status);
1654 hci_conn_del(sco);
1655 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001656 }
1657
1658 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001659}
1660
1661static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1662{
1663 struct hci_cp_sniff_mode *cp;
1664 struct hci_conn *conn;
1665
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001666 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001667
1668 if (!status)
1669 return;
1670
1671 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1672 if (!cp)
1673 return;
1674
1675 hci_dev_lock(hdev);
1676
1677 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001678 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001679 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001680
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001681 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001682 hci_sco_setup(conn, status);
1683 }
1684
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001685 hci_dev_unlock(hdev);
1686}
1687
1688static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1689{
1690 struct hci_cp_exit_sniff_mode *cp;
1691 struct hci_conn *conn;
1692
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001693 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001694
1695 if (!status)
1696 return;
1697
1698 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1699 if (!cp)
1700 return;
1701
1702 hci_dev_lock(hdev);
1703
1704 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001705 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001706 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001707
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001708 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001709 hci_sco_setup(conn, status);
1710 }
1711
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001712 hci_dev_unlock(hdev);
1713}
1714
Johan Hedberg88c3df12012-02-09 14:27:38 +02001715static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1716{
1717 struct hci_cp_disconnect *cp;
1718 struct hci_conn *conn;
1719
1720 if (!status)
1721 return;
1722
1723 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1724 if (!cp)
1725 return;
1726
1727 hci_dev_lock(hdev);
1728
1729 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1730 if (conn)
1731 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001732 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001733
1734 hci_dev_unlock(hdev);
1735}
1736
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001737static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1738{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001739 struct hci_cp_create_phy_link *cp;
1740
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001741 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001742
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001743 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1744 if (!cp)
1745 return;
1746
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001747 hci_dev_lock(hdev);
1748
1749 if (status) {
1750 struct hci_conn *hcon;
1751
1752 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1753 if (hcon)
1754 hci_conn_del(hcon);
1755 } else {
1756 amp_write_remote_assoc(hdev, cp->phy_handle);
1757 }
1758
1759 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001760}
1761
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001762static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1763{
1764 struct hci_cp_accept_phy_link *cp;
1765
1766 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1767
1768 if (status)
1769 return;
1770
1771 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1772 if (!cp)
1773 return;
1774
1775 amp_write_remote_assoc(hdev, cp->phy_handle);
1776}
1777
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001778static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
1779{
1780 struct hci_cp_le_create_conn *cp;
1781 struct hci_conn *conn;
1782
1783 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1784
1785 /* All connection failure handling is taken care of by the
1786 * hci_le_conn_failed function which is triggered by the HCI
1787 * request completion callbacks used for connecting.
1788 */
1789 if (status)
1790 return;
1791
1792 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1793 if (!cp)
1794 return;
1795
1796 hci_dev_lock(hdev);
1797
1798 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1799 if (!conn)
1800 goto unlock;
1801
1802 /* Store the initiator and responder address information which
1803 * is needed for SMP. These values will not change during the
1804 * lifetime of the connection.
1805 */
1806 conn->init_addr_type = cp->own_address_type;
1807 if (cp->own_address_type == ADDR_LE_DEV_RANDOM)
1808 bacpy(&conn->init_addr, &hdev->random_addr);
1809 else
1810 bacpy(&conn->init_addr, &hdev->bdaddr);
1811
1812 conn->resp_addr_type = cp->peer_addr_type;
1813 bacpy(&conn->resp_addr, &cp->peer_addr);
1814
Johan Hedberg9489eca2014-02-28 17:45:46 +02001815 /* We don't want the connection attempt to stick around
1816 * indefinitely since LE doesn't have a page timeout concept
1817 * like BR/EDR. Set a timer for any connection that doesn't use
1818 * the white list for connecting.
1819 */
1820 if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
1821 queue_delayed_work(conn->hdev->workqueue,
1822 &conn->le_conn_timeout,
1823 HCI_LE_CONN_TIMEOUT);
1824
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001825unlock:
1826 hci_dev_unlock(hdev);
1827}
1828
Johan Hedberg81d0c8a2014-03-24 14:39:04 +02001829static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1830{
1831 struct hci_cp_le_start_enc *cp;
1832 struct hci_conn *conn;
1833
1834 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1835
1836 if (!status)
1837 return;
1838
1839 hci_dev_lock(hdev);
1840
1841 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
1842 if (!cp)
1843 goto unlock;
1844
1845 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1846 if (!conn)
1847 goto unlock;
1848
1849 if (conn->state != BT_CONNECTED)
1850 goto unlock;
1851
1852 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
1853 hci_conn_drop(conn);
1854
1855unlock:
1856 hci_dev_unlock(hdev);
1857}
1858
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001859static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001860{
1861 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001862 struct discovery_state *discov = &hdev->discovery;
1863 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001864
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001865 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001866
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001867 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001868
1869 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1870 return;
1871
Andre Guedes3e13fa12013-03-27 20:04:56 -03001872 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1873 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1874
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001875 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001876 return;
1877
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001878 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001879
Andre Guedes343f9352012-02-17 20:39:37 -03001880 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001881 goto unlock;
1882
1883 if (list_empty(&discov->resolve)) {
1884 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1885 goto unlock;
1886 }
1887
1888 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1889 if (e && hci_resolve_name(hdev, e) == 0) {
1890 e->name_state = NAME_PENDING;
1891 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1892 } else {
1893 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1894 }
1895
1896unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001897 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001898}
1899
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001900static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001902 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001903 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 int num_rsp = *((__u8 *) skb->data);
1905
1906 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1907
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001908 if (!num_rsp)
1909 return;
1910
Andre Guedes1519cc12012-03-21 00:03:38 -03001911 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1912 return;
1913
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001915
Johan Hedberge17acd42011-03-30 23:57:16 +03001916 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001917 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001918
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 bacpy(&data.bdaddr, &info->bdaddr);
1920 data.pscan_rep_mode = info->pscan_rep_mode;
1921 data.pscan_period_mode = info->pscan_period_mode;
1922 data.pscan_mode = info->pscan_mode;
1923 memcpy(data.dev_class, info->dev_class, 3);
1924 data.clock_offset = info->clock_offset;
1925 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001926 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001927
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001928 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001929 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001930 info->dev_class, 0, !name_known, ssp, NULL,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02001931 0, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001933
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934 hci_dev_unlock(hdev);
1935}
1936
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001937static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001939 struct hci_ev_conn_complete *ev = (void *) skb->data;
1940 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001942 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001943
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001945
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001946 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001947 if (!conn) {
1948 if (ev->link_type != SCO_LINK)
1949 goto unlock;
1950
1951 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1952 if (!conn)
1953 goto unlock;
1954
1955 conn->type = SCO_LINK;
1956 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001957
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001958 if (!ev->status) {
1959 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001960
1961 if (conn->type == ACL_LINK) {
1962 conn->state = BT_CONFIG;
1963 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001964
1965 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1966 !hci_find_link_key(hdev, &ev->bdaddr))
1967 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1968 else
1969 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001970 } else
1971 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001972
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001973 hci_conn_add_sysfs(conn);
1974
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001975 if (test_bit(HCI_AUTH, &hdev->flags))
1976 conn->link_mode |= HCI_LM_AUTH;
1977
1978 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1979 conn->link_mode |= HCI_LM_ENCRYPT;
1980
1981 /* Get remote features */
1982 if (conn->type == ACL_LINK) {
1983 struct hci_cp_read_remote_features cp;
1984 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001985 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001986 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001987 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001988
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001989 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001990 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001991 struct hci_cp_change_conn_ptype cp;
1992 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001993 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001994 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1995 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001996 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001997 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001998 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001999 if (conn->type == ACL_LINK)
Marcel Holtmann64c7b772014-02-18 14:22:20 -08002000 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002001 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02002002 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002003
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002004 if (conn->type == ACL_LINK)
2005 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07002006
Marcel Holtmann769be972008-07-14 20:13:49 +02002007 if (ev->status) {
2008 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002009 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01002010 } else if (ev->link_type != ACL_LINK)
2011 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002012
2013unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002015
2016 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017}
2018
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002019static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002021 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002023 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002025 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002026 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002028 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
2029 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030
Szymon Janc138d22e2011-02-17 16:44:23 +01002031 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07002032 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02002034 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002036
2037 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002038
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002039 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2040 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02002041 memcpy(ie->data.dev_class, ev->dev_class, 3);
2042
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002043 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
2044 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002045 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002046 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
2047 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03002048 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049 hci_dev_unlock(hdev);
2050 return;
2051 }
2052 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002053
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002055
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056 hci_dev_unlock(hdev);
2057
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002058 if (ev->link_type == ACL_LINK ||
2059 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002060 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002061 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002063 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002065 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
2066 cp.role = 0x00; /* Become master */
2067 else
2068 cp.role = 0x01; /* Remain slave */
2069
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002070 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
2071 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002072 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002073 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002074 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002075
2076 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002077 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002078
Joe Perchesdcf4adb2014-03-12 10:52:35 -07002079 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
2080 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
2081 cp.max_latency = cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002082 cp.content_format = cpu_to_le16(hdev->voice_setting);
2083 cp.retrans_effort = 0xff;
2084
2085 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002086 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002087 } else {
2088 conn->state = BT_CONNECT2;
2089 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002090 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002091 } else {
2092 /* Connection rejected */
2093 struct hci_cp_reject_conn_req cp;
2094
2095 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002096 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002097 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098 }
2099}
2100
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02002101static u8 hci_to_mgmt_reason(u8 err)
2102{
2103 switch (err) {
2104 case HCI_ERROR_CONNECTION_TIMEOUT:
2105 return MGMT_DEV_DISCONN_TIMEOUT;
2106 case HCI_ERROR_REMOTE_USER_TERM:
2107 case HCI_ERROR_REMOTE_LOW_RESOURCES:
2108 case HCI_ERROR_REMOTE_POWER_OFF:
2109 return MGMT_DEV_DISCONN_REMOTE;
2110 case HCI_ERROR_LOCAL_HOST_TERM:
2111 return MGMT_DEV_DISCONN_LOCAL_HOST;
2112 default:
2113 return MGMT_DEV_DISCONN_UNKNOWN;
2114 }
2115}
2116
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002117static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002119 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03002120 u8 reason = hci_to_mgmt_reason(ev->reason);
Andre Guedes9fcb18e2014-02-26 20:21:48 -03002121 struct hci_conn_params *params;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002122 struct hci_conn *conn;
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02002123 bool mgmt_connected;
Andre Guedes38462202013-11-07 17:36:10 -03002124 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002126 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128 hci_dev_lock(hdev);
2129
Marcel Holtmann04837f62006-07-03 10:02:33 +02002130 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02002131 if (!conn)
2132 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002133
Andre Guedesabf54a52013-11-07 17:36:09 -03002134 if (ev->status) {
2135 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
2136 conn->dst_type, ev->status);
2137 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002138 }
Johan Hedbergf7520542011-01-20 12:34:39 +02002139
Andre Guedes38462202013-11-07 17:36:10 -03002140 conn->state = BT_CLOSED;
2141
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02002142 mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
2143 mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
2144 reason, mgmt_connected);
Andre Guedesabf54a52013-11-07 17:36:09 -03002145
Andre Guedes38462202013-11-07 17:36:10 -03002146 if (conn->type == ACL_LINK && conn->flush_key)
2147 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg22102462013-10-05 12:01:06 +02002148
Andre Guedes9fcb18e2014-02-26 20:21:48 -03002149 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
2150 if (params) {
2151 switch (params->auto_connect) {
2152 case HCI_AUTO_CONN_LINK_LOSS:
2153 if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
2154 break;
2155 /* Fall through */
2156
2157 case HCI_AUTO_CONN_ALWAYS:
2158 hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
2159 break;
2160
2161 default:
2162 break;
2163 }
2164 }
2165
Andre Guedes38462202013-11-07 17:36:10 -03002166 type = conn->type;
Johan Hedberg22102462013-10-05 12:01:06 +02002167
Andre Guedes38462202013-11-07 17:36:10 -03002168 hci_proto_disconn_cfm(conn, ev->reason);
2169 hci_conn_del(conn);
2170
2171 /* Re-enable advertising if necessary, since it might
2172 * have been disabled by the connection. From the
2173 * HCI_LE_Set_Advertise_Enable command description in
2174 * the core specification (v4.0):
2175 * "The Controller shall continue advertising until the Host
2176 * issues an LE_Set_Advertise_Enable command with
2177 * Advertising_Enable set to 0x00 (Advertising is disabled)
2178 * or until a connection is created or until the Advertising
2179 * is timed out due to Directed Advertising."
2180 */
2181 if (type == LE_LINK)
2182 mgmt_reenable_advertising(hdev);
Johan Hedbergf7520542011-01-20 12:34:39 +02002183
2184unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002185 hci_dev_unlock(hdev);
2186}
2187
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002188static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002189{
2190 struct hci_ev_auth_complete *ev = (void *) skb->data;
2191 struct hci_conn *conn;
2192
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002193 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002194
2195 hci_dev_lock(hdev);
2196
2197 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002198 if (!conn)
2199 goto unlock;
2200
2201 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002202 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002203 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002204 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03002205 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002206 conn->link_mode |= HCI_LM_AUTH;
2207 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03002208 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002209 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02002210 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002211 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002212 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002213
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002214 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
2215 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002216
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002217 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002218 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002219 struct hci_cp_set_conn_encrypt cp;
2220 cp.handle = ev->handle;
2221 cp.encrypt = 0x01;
2222 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002223 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002224 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002225 conn->state = BT_CONNECTED;
2226 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002227 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002228 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002229 } else {
2230 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002231
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002232 hci_conn_hold(conn);
2233 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002234 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002235 }
2236
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002237 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002238 if (!ev->status) {
2239 struct hci_cp_set_conn_encrypt cp;
2240 cp.handle = ev->handle;
2241 cp.encrypt = 0x01;
2242 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002243 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002244 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002245 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002246 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002247 }
2248 }
2249
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002250unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002251 hci_dev_unlock(hdev);
2252}
2253
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002254static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002255{
Johan Hedberg127178d2010-11-18 22:22:29 +02002256 struct hci_ev_remote_name *ev = (void *) skb->data;
2257 struct hci_conn *conn;
2258
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002259 BT_DBG("%s", hdev->name);
2260
2261 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002262
2263 hci_dev_lock(hdev);
2264
2265 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002266
2267 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2268 goto check_auth;
2269
2270 if (ev->status == 0)
2271 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002272 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002273 else
2274 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2275
2276check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002277 if (!conn)
2278 goto unlock;
2279
2280 if (!hci_outgoing_auth_needed(hdev, conn))
2281 goto unlock;
2282
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002283 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002284 struct hci_cp_auth_requested cp;
2285 cp.handle = __cpu_to_le16(conn->handle);
2286 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2287 }
2288
Johan Hedberg79c6c702011-04-28 11:28:55 -07002289unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002290 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002291}
2292
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002293static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002294{
2295 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2296 struct hci_conn *conn;
2297
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002298 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002299
2300 hci_dev_lock(hdev);
2301
2302 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002303 if (!conn)
2304 goto unlock;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002305
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002306 if (!ev->status) {
2307 if (ev->encrypt) {
2308 /* Encryption implies authentication */
2309 conn->link_mode |= HCI_LM_AUTH;
2310 conn->link_mode |= HCI_LM_ENCRYPT;
2311 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002312
Marcel Holtmann914a6ff2014-02-01 11:52:02 -08002313 /* P-256 authentication key implies FIPS */
2314 if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
2315 conn->link_mode |= HCI_LM_FIPS;
2316
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002317 if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2318 conn->type == LE_LINK)
2319 set_bit(HCI_CONN_AES_CCM, &conn->flags);
2320 } else {
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002321 conn->link_mode &= ~HCI_LM_ENCRYPT;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002322 clear_bit(HCI_CONN_AES_CCM, &conn->flags);
2323 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002324 }
2325
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002326 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2327
2328 if (ev->status && conn->state == BT_CONNECTED) {
2329 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
2330 hci_conn_drop(conn);
2331 goto unlock;
2332 }
2333
2334 if (conn->state == BT_CONFIG) {
2335 if (!ev->status)
2336 conn->state = BT_CONNECTED;
2337
Marcel Holtmann40b552a2014-03-19 14:10:25 -07002338 /* In Secure Connections Only mode, do not allow any
2339 * connections that are not encrypted with AES-CCM
2340 * using a P-256 authenticated combination key.
2341 */
2342 if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) &&
2343 (!test_bit(HCI_CONN_AES_CCM, &conn->flags) ||
2344 conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) {
2345 hci_proto_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE);
2346 hci_conn_drop(conn);
2347 goto unlock;
2348 }
2349
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002350 hci_proto_connect_cfm(conn, ev->status);
2351 hci_conn_drop(conn);
2352 } else
2353 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2354
Gustavo Padovana7d77232012-05-13 03:20:07 -03002355unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002356 hci_dev_unlock(hdev);
2357}
2358
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002359static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2360 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002361{
2362 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2363 struct hci_conn *conn;
2364
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002365 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002366
2367 hci_dev_lock(hdev);
2368
2369 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2370 if (conn) {
2371 if (!ev->status)
2372 conn->link_mode |= HCI_LM_SECURE;
2373
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002374 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002375
2376 hci_key_change_cfm(conn, ev->status);
2377 }
2378
2379 hci_dev_unlock(hdev);
2380}
2381
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002382static void hci_remote_features_evt(struct hci_dev *hdev,
2383 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002384{
2385 struct hci_ev_remote_features *ev = (void *) skb->data;
2386 struct hci_conn *conn;
2387
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002388 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002389
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002390 hci_dev_lock(hdev);
2391
2392 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002393 if (!conn)
2394 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002395
Johan Hedbergccd556f2010-11-10 17:11:51 +02002396 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002397 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002398
2399 if (conn->state != BT_CONFIG)
2400 goto unlock;
2401
2402 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2403 struct hci_cp_read_remote_ext_features cp;
2404 cp.handle = ev->handle;
2405 cp.page = 0x01;
2406 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002407 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002408 goto unlock;
2409 }
2410
Johan Hedberg671267b2012-05-12 16:11:50 -03002411 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002412 struct hci_cp_remote_name_req cp;
2413 memset(&cp, 0, sizeof(cp));
2414 bacpy(&cp.bdaddr, &conn->dst);
2415 cp.pscan_rep_mode = 0x02;
2416 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002417 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2418 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002419 conn->dst_type, 0, NULL, 0,
2420 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002421
Johan Hedberg127178d2010-11-18 22:22:29 +02002422 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002423 conn->state = BT_CONNECTED;
2424 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002425 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002426 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002427
Johan Hedbergccd556f2010-11-10 17:11:51 +02002428unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002429 hci_dev_unlock(hdev);
2430}
2431
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002432static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002433{
2434 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002435 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002436 __u16 opcode;
2437
2438 skb_pull(skb, sizeof(*ev));
2439
2440 opcode = __le16_to_cpu(ev->opcode);
2441
2442 switch (opcode) {
2443 case HCI_OP_INQUIRY_CANCEL:
2444 hci_cc_inquiry_cancel(hdev, skb);
2445 break;
2446
Andre Guedes4d934832012-03-21 00:03:35 -03002447 case HCI_OP_PERIODIC_INQ:
2448 hci_cc_periodic_inq(hdev, skb);
2449 break;
2450
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002451 case HCI_OP_EXIT_PERIODIC_INQ:
2452 hci_cc_exit_periodic_inq(hdev, skb);
2453 break;
2454
2455 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2456 hci_cc_remote_name_req_cancel(hdev, skb);
2457 break;
2458
2459 case HCI_OP_ROLE_DISCOVERY:
2460 hci_cc_role_discovery(hdev, skb);
2461 break;
2462
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002463 case HCI_OP_READ_LINK_POLICY:
2464 hci_cc_read_link_policy(hdev, skb);
2465 break;
2466
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002467 case HCI_OP_WRITE_LINK_POLICY:
2468 hci_cc_write_link_policy(hdev, skb);
2469 break;
2470
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002471 case HCI_OP_READ_DEF_LINK_POLICY:
2472 hci_cc_read_def_link_policy(hdev, skb);
2473 break;
2474
2475 case HCI_OP_WRITE_DEF_LINK_POLICY:
2476 hci_cc_write_def_link_policy(hdev, skb);
2477 break;
2478
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002479 case HCI_OP_RESET:
2480 hci_cc_reset(hdev, skb);
2481 break;
2482
2483 case HCI_OP_WRITE_LOCAL_NAME:
2484 hci_cc_write_local_name(hdev, skb);
2485 break;
2486
2487 case HCI_OP_READ_LOCAL_NAME:
2488 hci_cc_read_local_name(hdev, skb);
2489 break;
2490
2491 case HCI_OP_WRITE_AUTH_ENABLE:
2492 hci_cc_write_auth_enable(hdev, skb);
2493 break;
2494
2495 case HCI_OP_WRITE_ENCRYPT_MODE:
2496 hci_cc_write_encrypt_mode(hdev, skb);
2497 break;
2498
2499 case HCI_OP_WRITE_SCAN_ENABLE:
2500 hci_cc_write_scan_enable(hdev, skb);
2501 break;
2502
2503 case HCI_OP_READ_CLASS_OF_DEV:
2504 hci_cc_read_class_of_dev(hdev, skb);
2505 break;
2506
2507 case HCI_OP_WRITE_CLASS_OF_DEV:
2508 hci_cc_write_class_of_dev(hdev, skb);
2509 break;
2510
2511 case HCI_OP_READ_VOICE_SETTING:
2512 hci_cc_read_voice_setting(hdev, skb);
2513 break;
2514
2515 case HCI_OP_WRITE_VOICE_SETTING:
2516 hci_cc_write_voice_setting(hdev, skb);
2517 break;
2518
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002519 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2520 hci_cc_read_num_supported_iac(hdev, skb);
2521 break;
2522
Marcel Holtmann333140b2008-07-14 20:13:48 +02002523 case HCI_OP_WRITE_SSP_MODE:
2524 hci_cc_write_ssp_mode(hdev, skb);
2525 break;
2526
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08002527 case HCI_OP_WRITE_SC_SUPPORT:
2528 hci_cc_write_sc_support(hdev, skb);
2529 break;
2530
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002531 case HCI_OP_READ_LOCAL_VERSION:
2532 hci_cc_read_local_version(hdev, skb);
2533 break;
2534
2535 case HCI_OP_READ_LOCAL_COMMANDS:
2536 hci_cc_read_local_commands(hdev, skb);
2537 break;
2538
2539 case HCI_OP_READ_LOCAL_FEATURES:
2540 hci_cc_read_local_features(hdev, skb);
2541 break;
2542
Andre Guedes971e3a42011-06-30 19:20:52 -03002543 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2544 hci_cc_read_local_ext_features(hdev, skb);
2545 break;
2546
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002547 case HCI_OP_READ_BUFFER_SIZE:
2548 hci_cc_read_buffer_size(hdev, skb);
2549 break;
2550
2551 case HCI_OP_READ_BD_ADDR:
2552 hci_cc_read_bd_addr(hdev, skb);
2553 break;
2554
Johan Hedbergf332ec62013-03-15 17:07:11 -05002555 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2556 hci_cc_read_page_scan_activity(hdev, skb);
2557 break;
2558
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002559 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2560 hci_cc_write_page_scan_activity(hdev, skb);
2561 break;
2562
Johan Hedbergf332ec62013-03-15 17:07:11 -05002563 case HCI_OP_READ_PAGE_SCAN_TYPE:
2564 hci_cc_read_page_scan_type(hdev, skb);
2565 break;
2566
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002567 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2568 hci_cc_write_page_scan_type(hdev, skb);
2569 break;
2570
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002571 case HCI_OP_READ_DATA_BLOCK_SIZE:
2572 hci_cc_read_data_block_size(hdev, skb);
2573 break;
2574
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002575 case HCI_OP_READ_FLOW_CONTROL_MODE:
2576 hci_cc_read_flow_control_mode(hdev, skb);
2577 break;
2578
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002579 case HCI_OP_READ_LOCAL_AMP_INFO:
2580 hci_cc_read_local_amp_info(hdev, skb);
2581 break;
2582
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002583 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2584 hci_cc_read_local_amp_assoc(hdev, skb);
2585 break;
2586
Johan Hedbergd5859e22011-01-25 01:19:58 +02002587 case HCI_OP_READ_INQ_RSP_TX_POWER:
2588 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2589 break;
2590
Johan Hedberg980e1a52011-01-22 06:10:07 +02002591 case HCI_OP_PIN_CODE_REPLY:
2592 hci_cc_pin_code_reply(hdev, skb);
2593 break;
2594
2595 case HCI_OP_PIN_CODE_NEG_REPLY:
2596 hci_cc_pin_code_neg_reply(hdev, skb);
2597 break;
2598
Szymon Jancc35938b2011-03-22 13:12:21 +01002599 case HCI_OP_READ_LOCAL_OOB_DATA:
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08002600 hci_cc_read_local_oob_data(hdev, skb);
2601 break;
2602
2603 case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
2604 hci_cc_read_local_oob_ext_data(hdev, skb);
Szymon Jancc35938b2011-03-22 13:12:21 +01002605 break;
2606
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002607 case HCI_OP_LE_READ_BUFFER_SIZE:
2608 hci_cc_le_read_buffer_size(hdev, skb);
2609 break;
2610
Johan Hedberg60e77322013-01-22 14:01:59 +02002611 case HCI_OP_LE_READ_LOCAL_FEATURES:
2612 hci_cc_le_read_local_features(hdev, skb);
2613 break;
2614
Johan Hedberg8fa19092012-10-19 20:57:49 +03002615 case HCI_OP_LE_READ_ADV_TX_POWER:
2616 hci_cc_le_read_adv_tx_power(hdev, skb);
2617 break;
2618
Johan Hedberga5c29682011-02-19 12:05:57 -03002619 case HCI_OP_USER_CONFIRM_REPLY:
2620 hci_cc_user_confirm_reply(hdev, skb);
2621 break;
2622
2623 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2624 hci_cc_user_confirm_neg_reply(hdev, skb);
2625 break;
2626
Brian Gix1143d452011-11-23 08:28:34 -08002627 case HCI_OP_USER_PASSKEY_REPLY:
2628 hci_cc_user_passkey_reply(hdev, skb);
2629 break;
2630
2631 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2632 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002633 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002634
Marcel Holtmann7a4cd512014-02-19 19:52:13 -08002635 case HCI_OP_LE_SET_RANDOM_ADDR:
2636 hci_cc_le_set_random_addr(hdev, skb);
2637 break;
2638
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002639 case HCI_OP_LE_SET_ADV_ENABLE:
2640 hci_cc_le_set_adv_enable(hdev, skb);
2641 break;
2642
Marcel Holtmann533553f2014-03-21 12:18:10 -07002643 case HCI_OP_LE_SET_SCAN_PARAM:
2644 hci_cc_le_set_scan_param(hdev, skb);
2645 break;
2646
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002647 case HCI_OP_LE_SET_SCAN_ENABLE:
2648 hci_cc_le_set_scan_enable(hdev, skb);
2649 break;
2650
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002651 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2652 hci_cc_le_read_white_list_size(hdev, skb);
2653 break;
2654
Marcel Holtmann0f36b582014-02-27 20:37:31 -08002655 case HCI_OP_LE_CLEAR_WHITE_LIST:
2656 hci_cc_le_clear_white_list(hdev, skb);
2657 break;
2658
2659 case HCI_OP_LE_ADD_TO_WHITE_LIST:
2660 hci_cc_le_add_to_white_list(hdev, skb);
2661 break;
2662
2663 case HCI_OP_LE_DEL_FROM_WHITE_LIST:
2664 hci_cc_le_del_from_white_list(hdev, skb);
2665 break;
2666
Johan Hedberg9b008c02013-01-22 14:02:01 +02002667 case HCI_OP_LE_READ_SUPPORTED_STATES:
2668 hci_cc_le_read_supported_states(hdev, skb);
2669 break;
2670
Andre Guedesf9b49302011-06-30 19:20:53 -03002671 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2672 hci_cc_write_le_host_supported(hdev, skb);
2673 break;
2674
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02002675 case HCI_OP_LE_SET_ADV_PARAM:
2676 hci_cc_set_adv_param(hdev, skb);
2677 break;
2678
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002679 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2680 hci_cc_write_remote_amp_assoc(hdev, skb);
2681 break;
2682
Andrzej Kaczmarek5ae76a92014-05-08 15:32:08 +02002683 case HCI_OP_READ_RSSI:
2684 hci_cc_read_rssi(hdev, skb);
2685 break;
2686
Andrzej Kaczmarek5a134fa2014-05-09 21:35:28 +02002687 case HCI_OP_READ_TX_POWER:
2688 hci_cc_read_tx_power(hdev, skb);
2689 break;
2690
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002691 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002692 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002693 break;
2694 }
2695
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002696 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002697 del_timer(&hdev->cmd_timer);
2698
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002699 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002700
Szymon Jancdbccd792012-12-11 08:51:19 +01002701 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002702 atomic_set(&hdev->cmd_cnt, 1);
2703 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002704 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002705 }
2706}
2707
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002708static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002709{
2710 struct hci_ev_cmd_status *ev = (void *) skb->data;
2711 __u16 opcode;
2712
2713 skb_pull(skb, sizeof(*ev));
2714
2715 opcode = __le16_to_cpu(ev->opcode);
2716
2717 switch (opcode) {
2718 case HCI_OP_INQUIRY:
2719 hci_cs_inquiry(hdev, ev->status);
2720 break;
2721
2722 case HCI_OP_CREATE_CONN:
2723 hci_cs_create_conn(hdev, ev->status);
2724 break;
2725
2726 case HCI_OP_ADD_SCO:
2727 hci_cs_add_sco(hdev, ev->status);
2728 break;
2729
Marcel Holtmannf8558552008-07-14 20:13:49 +02002730 case HCI_OP_AUTH_REQUESTED:
2731 hci_cs_auth_requested(hdev, ev->status);
2732 break;
2733
2734 case HCI_OP_SET_CONN_ENCRYPT:
2735 hci_cs_set_conn_encrypt(hdev, ev->status);
2736 break;
2737
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002738 case HCI_OP_REMOTE_NAME_REQ:
2739 hci_cs_remote_name_req(hdev, ev->status);
2740 break;
2741
Marcel Holtmann769be972008-07-14 20:13:49 +02002742 case HCI_OP_READ_REMOTE_FEATURES:
2743 hci_cs_read_remote_features(hdev, ev->status);
2744 break;
2745
2746 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2747 hci_cs_read_remote_ext_features(hdev, ev->status);
2748 break;
2749
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002750 case HCI_OP_SETUP_SYNC_CONN:
2751 hci_cs_setup_sync_conn(hdev, ev->status);
2752 break;
2753
2754 case HCI_OP_SNIFF_MODE:
2755 hci_cs_sniff_mode(hdev, ev->status);
2756 break;
2757
2758 case HCI_OP_EXIT_SNIFF_MODE:
2759 hci_cs_exit_sniff_mode(hdev, ev->status);
2760 break;
2761
Johan Hedberg8962ee72011-01-20 12:40:27 +02002762 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002763 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002764 break;
2765
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002766 case HCI_OP_CREATE_PHY_LINK:
2767 hci_cs_create_phylink(hdev, ev->status);
2768 break;
2769
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002770 case HCI_OP_ACCEPT_PHY_LINK:
2771 hci_cs_accept_phylink(hdev, ev->status);
2772 break;
2773
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02002774 case HCI_OP_LE_CREATE_CONN:
2775 hci_cs_le_create_conn(hdev, ev->status);
2776 break;
2777
Johan Hedberg81d0c8a2014-03-24 14:39:04 +02002778 case HCI_OP_LE_START_ENC:
2779 hci_cs_le_start_enc(hdev, ev->status);
2780 break;
2781
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002782 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002783 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002784 break;
2785 }
2786
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002787 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002788 del_timer(&hdev->cmd_timer);
2789
Johan Hedberg02350a72013-04-03 21:50:29 +03002790 if (ev->status ||
2791 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2792 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002793
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002794 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002795 atomic_set(&hdev->cmd_cnt, 1);
2796 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002797 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002798 }
2799}
2800
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002801static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002802{
2803 struct hci_ev_role_change *ev = (void *) skb->data;
2804 struct hci_conn *conn;
2805
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002806 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002807
2808 hci_dev_lock(hdev);
2809
2810 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2811 if (conn) {
2812 if (!ev->status) {
2813 if (ev->role)
2814 conn->link_mode &= ~HCI_LM_MASTER;
2815 else
2816 conn->link_mode |= HCI_LM_MASTER;
2817 }
2818
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002819 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002820
2821 hci_role_switch_cfm(conn, ev->status, ev->role);
2822 }
2823
2824 hci_dev_unlock(hdev);
2825}
2826
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002827static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002828{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002829 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830 int i;
2831
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002832 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2833 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2834 return;
2835 }
2836
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002837 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002838 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002839 BT_DBG("%s bad parameters", hdev->name);
2840 return;
2841 }
2842
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002843 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2844
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002845 for (i = 0; i < ev->num_hndl; i++) {
2846 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847 struct hci_conn *conn;
2848 __u16 handle, count;
2849
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002850 handle = __le16_to_cpu(info->handle);
2851 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002852
2853 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002854 if (!conn)
2855 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002857 conn->sent -= count;
2858
2859 switch (conn->type) {
2860 case ACL_LINK:
2861 hdev->acl_cnt += count;
2862 if (hdev->acl_cnt > hdev->acl_pkts)
2863 hdev->acl_cnt = hdev->acl_pkts;
2864 break;
2865
2866 case LE_LINK:
2867 if (hdev->le_pkts) {
2868 hdev->le_cnt += count;
2869 if (hdev->le_cnt > hdev->le_pkts)
2870 hdev->le_cnt = hdev->le_pkts;
2871 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002872 hdev->acl_cnt += count;
2873 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874 hdev->acl_cnt = hdev->acl_pkts;
2875 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002876 break;
2877
2878 case SCO_LINK:
2879 hdev->sco_cnt += count;
2880 if (hdev->sco_cnt > hdev->sco_pkts)
2881 hdev->sco_cnt = hdev->sco_pkts;
2882 break;
2883
2884 default:
2885 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2886 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887 }
2888 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002889
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002890 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002891}
2892
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002893static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2894 __u16 handle)
2895{
2896 struct hci_chan *chan;
2897
2898 switch (hdev->dev_type) {
2899 case HCI_BREDR:
2900 return hci_conn_hash_lookup_handle(hdev, handle);
2901 case HCI_AMP:
2902 chan = hci_chan_lookup_handle(hdev, handle);
2903 if (chan)
2904 return chan->conn;
2905 break;
2906 default:
2907 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2908 break;
2909 }
2910
2911 return NULL;
2912}
2913
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002914static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002915{
2916 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2917 int i;
2918
2919 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2920 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2921 return;
2922 }
2923
2924 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002925 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002926 BT_DBG("%s bad parameters", hdev->name);
2927 return;
2928 }
2929
2930 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002931 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002932
2933 for (i = 0; i < ev->num_hndl; i++) {
2934 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002935 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002936 __u16 handle, block_count;
2937
2938 handle = __le16_to_cpu(info->handle);
2939 block_count = __le16_to_cpu(info->blocks);
2940
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002941 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002942 if (!conn)
2943 continue;
2944
2945 conn->sent -= block_count;
2946
2947 switch (conn->type) {
2948 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002949 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002950 hdev->block_cnt += block_count;
2951 if (hdev->block_cnt > hdev->num_blocks)
2952 hdev->block_cnt = hdev->num_blocks;
2953 break;
2954
2955 default:
2956 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2957 break;
2958 }
2959 }
2960
2961 queue_work(hdev->workqueue, &hdev->tx_work);
2962}
2963
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002964static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002965{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002966 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002967 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002969 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002970
2971 hci_dev_lock(hdev);
2972
Marcel Holtmann04837f62006-07-03 10:02:33 +02002973 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2974 if (conn) {
2975 conn->mode = ev->mode;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002976
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002977 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2978 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002979 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002980 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002981 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002982 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002983 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002984
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002985 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002986 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002987 }
2988
2989 hci_dev_unlock(hdev);
2990}
2991
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002992static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002994 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2995 struct hci_conn *conn;
2996
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002997 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002998
2999 hci_dev_lock(hdev);
3000
3001 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02003002 if (!conn)
3003 goto unlock;
3004
3005 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003006 hci_conn_hold(conn);
3007 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003008 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003009 }
3010
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003011 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003012 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003013 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003014 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02003015 u8 secure;
3016
3017 if (conn->pending_sec_level == BT_SECURITY_HIGH)
3018 secure = 1;
3019 else
3020 secure = 0;
3021
Johan Hedberg744cf192011-11-08 20:40:14 +02003022 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02003023 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02003024
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02003025unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003026 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003027}
3028
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003029static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003030{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003031 struct hci_ev_link_key_req *ev = (void *) skb->data;
3032 struct hci_cp_link_key_reply cp;
3033 struct hci_conn *conn;
3034 struct link_key *key;
3035
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003036 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003037
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03003038 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003039 return;
3040
3041 hci_dev_lock(hdev);
3042
3043 key = hci_find_link_key(hdev, &ev->bdaddr);
3044 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03003045 BT_DBG("%s link key not found for %pMR", hdev->name,
3046 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003047 goto not_found;
3048 }
3049
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03003050 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
3051 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003052
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003053 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003054 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003055 BT_DBG("%s ignoring debug key", hdev->name);
3056 goto not_found;
3057 }
3058
3059 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003060 if (conn) {
Marcel Holtmann66138ce2014-01-10 02:07:20 -08003061 if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
3062 key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003063 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003064 BT_DBG("%s ignoring unauthenticated key", hdev->name);
3065 goto not_found;
3066 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003067
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003068 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003069 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003070 BT_DBG("%s ignoring key unauthenticated for high security",
3071 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003072 goto not_found;
3073 }
3074
3075 conn->key_type = key->type;
3076 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003077 }
3078
3079 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03003080 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003081
3082 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
3083
3084 hci_dev_unlock(hdev);
3085
3086 return;
3087
3088not_found:
3089 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
3090 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003091}
3092
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003093static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003094{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003095 struct hci_ev_link_key_notify *ev = (void *) skb->data;
3096 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003097 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003098
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003099 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003100
3101 hci_dev_lock(hdev);
3102
3103 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3104 if (conn) {
3105 hci_conn_hold(conn);
3106 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02003107 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02003108
3109 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
3110 conn->key_type = ev->key_type;
3111
David Herrmann76a68ba2013-04-06 20:28:37 +02003112 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003113 }
3114
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03003115 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07003116 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003117 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003118
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003119 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120}
3121
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003122static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02003123{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003124 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02003125 struct hci_conn *conn;
3126
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003127 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02003128
3129 hci_dev_lock(hdev);
3130
3131 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003132 if (conn && !ev->status) {
3133 struct inquiry_entry *ie;
3134
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003135 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3136 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003137 ie->data.clock_offset = ev->clock_offset;
3138 ie->timestamp = jiffies;
3139 }
3140 }
3141
3142 hci_dev_unlock(hdev);
3143}
3144
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003145static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02003146{
3147 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
3148 struct hci_conn *conn;
3149
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003150 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02003151
3152 hci_dev_lock(hdev);
3153
3154 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3155 if (conn && !ev->status)
3156 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
3157
3158 hci_dev_unlock(hdev);
3159}
3160
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003161static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003162{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003163 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003164 struct inquiry_entry *ie;
3165
3166 BT_DBG("%s", hdev->name);
3167
3168 hci_dev_lock(hdev);
3169
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003170 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3171 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003172 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
3173 ie->timestamp = jiffies;
3174 }
3175
3176 hci_dev_unlock(hdev);
3177}
3178
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003179static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
3180 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003181{
3182 struct inquiry_data data;
3183 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003184 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003185
3186 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3187
3188 if (!num_rsp)
3189 return;
3190
Andre Guedes1519cc12012-03-21 00:03:38 -03003191 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3192 return;
3193
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003194 hci_dev_lock(hdev);
3195
3196 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01003197 struct inquiry_info_with_rssi_and_pscan_mode *info;
3198 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003199
Johan Hedberge17acd42011-03-30 23:57:16 +03003200 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003201 bacpy(&data.bdaddr, &info->bdaddr);
3202 data.pscan_rep_mode = info->pscan_rep_mode;
3203 data.pscan_period_mode = info->pscan_period_mode;
3204 data.pscan_mode = info->pscan_mode;
3205 memcpy(data.dev_class, info->dev_class, 3);
3206 data.clock_offset = info->clock_offset;
3207 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003208 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003209
3210 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003211 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003212 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003213 info->dev_class, info->rssi,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02003214 !name_known, ssp, NULL, 0, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003215 }
3216 } else {
3217 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
3218
Johan Hedberge17acd42011-03-30 23:57:16 +03003219 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003220 bacpy(&data.bdaddr, &info->bdaddr);
3221 data.pscan_rep_mode = info->pscan_rep_mode;
3222 data.pscan_period_mode = info->pscan_period_mode;
3223 data.pscan_mode = 0x00;
3224 memcpy(data.dev_class, info->dev_class, 3);
3225 data.clock_offset = info->clock_offset;
3226 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003227 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003228 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003229 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003230 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003231 info->dev_class, info->rssi,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02003232 !name_known, ssp, NULL, 0, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003233 }
3234 }
3235
3236 hci_dev_unlock(hdev);
3237}
3238
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003239static void hci_remote_ext_features_evt(struct hci_dev *hdev,
3240 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003241{
Marcel Holtmann41a96212008-07-14 20:13:48 +02003242 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
3243 struct hci_conn *conn;
3244
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003245 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003246
Marcel Holtmann41a96212008-07-14 20:13:48 +02003247 hci_dev_lock(hdev);
3248
3249 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02003250 if (!conn)
3251 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003252
Johan Hedbergcad718e2013-04-17 15:00:51 +03003253 if (ev->page < HCI_MAX_PAGES)
3254 memcpy(conn->features[ev->page], ev->features, 8);
3255
Johan Hedbergccd556f2010-11-10 17:11:51 +02003256 if (!ev->status && ev->page == 0x01) {
3257 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003258
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003259 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3260 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003261 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02003262
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303263 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02003264 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303265 } else {
3266 /* It is mandatory by the Bluetooth specification that
3267 * Extended Inquiry Results are only used when Secure
3268 * Simple Pairing is enabled, but some devices violate
3269 * this.
3270 *
3271 * To make these devices work, the internal SSP
3272 * enabled flag needs to be cleared if the remote host
3273 * features do not indicate SSP support */
3274 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
3275 }
Marcel Holtmanneb9a8f32014-01-15 22:37:38 -08003276
3277 if (ev->features[0] & LMP_HOST_SC)
3278 set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003279 }
3280
Johan Hedbergccd556f2010-11-10 17:11:51 +02003281 if (conn->state != BT_CONFIG)
3282 goto unlock;
3283
Johan Hedberg671267b2012-05-12 16:11:50 -03003284 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02003285 struct hci_cp_remote_name_req cp;
3286 memset(&cp, 0, sizeof(cp));
3287 bacpy(&cp.bdaddr, &conn->dst);
3288 cp.pscan_rep_mode = 0x02;
3289 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02003290 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3291 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003292 conn->dst_type, 0, NULL, 0,
3293 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02003294
Johan Hedberg127178d2010-11-18 22:22:29 +02003295 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02003296 conn->state = BT_CONNECTED;
3297 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003298 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02003299 }
3300
3301unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02003302 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003303}
3304
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003305static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3306 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003307{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003308 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3309 struct hci_conn *conn;
3310
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003311 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003312
3313 hci_dev_lock(hdev);
3314
3315 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02003316 if (!conn) {
3317 if (ev->link_type == ESCO_LINK)
3318 goto unlock;
3319
3320 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3321 if (!conn)
3322 goto unlock;
3323
3324 conn->type = SCO_LINK;
3325 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003326
Marcel Holtmann732547f2009-04-19 19:14:14 +02003327 switch (ev->status) {
3328 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003329 conn->handle = __le16_to_cpu(ev->handle);
3330 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003331
3332 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02003333 break;
3334
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02003335 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05003336 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003337 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08003338 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003339 case 0x1f: /* Unspecified error */
Andrew Earl27539bc2014-03-10 10:31:04 +00003340 case 0x20: /* Unsupported LMP Parameter value */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003341 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02003342 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3343 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003344 if (hci_setup_sync(conn, conn->link->handle))
3345 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003346 }
3347 /* fall through */
3348
3349 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003350 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003351 break;
3352 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003353
3354 hci_proto_connect_cfm(conn, ev->status);
3355 if (ev->status)
3356 hci_conn_del(conn);
3357
3358unlock:
3359 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003360}
3361
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07003362static inline size_t eir_get_length(u8 *eir, size_t eir_len)
3363{
3364 size_t parsed = 0;
3365
3366 while (parsed < eir_len) {
3367 u8 field_len = eir[0];
3368
3369 if (field_len == 0)
3370 return parsed;
3371
3372 parsed += field_len + 1;
3373 eir += field_len + 1;
3374 }
3375
3376 return eir_len;
3377}
3378
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003379static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3380 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003381{
3382 struct inquiry_data data;
3383 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3384 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303385 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003386
3387 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3388
3389 if (!num_rsp)
3390 return;
3391
Andre Guedes1519cc12012-03-21 00:03:38 -03003392 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3393 return;
3394
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003395 hci_dev_lock(hdev);
3396
Johan Hedberge17acd42011-03-30 23:57:16 +03003397 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003398 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003399
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003400 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003401 data.pscan_rep_mode = info->pscan_rep_mode;
3402 data.pscan_period_mode = info->pscan_period_mode;
3403 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003404 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003405 data.clock_offset = info->clock_offset;
3406 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003407 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003408
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003409 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003410 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003411 sizeof(info->data),
3412 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003413 else
3414 name_known = true;
3415
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003416 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003417 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303418 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003419 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003420 info->dev_class, info->rssi, !name_known,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02003421 ssp, info->data, eir_len, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003422 }
3423
3424 hci_dev_unlock(hdev);
3425}
3426
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003427static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3428 struct sk_buff *skb)
3429{
3430 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3431 struct hci_conn *conn;
3432
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003433 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003434 __le16_to_cpu(ev->handle));
3435
3436 hci_dev_lock(hdev);
3437
3438 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3439 if (!conn)
3440 goto unlock;
3441
3442 if (!ev->status)
3443 conn->sec_level = conn->pending_sec_level;
3444
3445 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3446
3447 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003448 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003449 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003450 goto unlock;
3451 }
3452
3453 if (conn->state == BT_CONFIG) {
3454 if (!ev->status)
3455 conn->state = BT_CONNECTED;
3456
3457 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003458 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003459 } else {
3460 hci_auth_cfm(conn, ev->status);
3461
3462 hci_conn_hold(conn);
3463 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003464 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003465 }
3466
3467unlock:
3468 hci_dev_unlock(hdev);
3469}
3470
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003471static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003472{
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003473 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003474 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3475 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003476 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003477
Mikel Astizb7f94c82014-04-08 14:21:31 +02003478 /* If both remote and local have enough IO capabilities, require
3479 * MITM protection
3480 */
3481 if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT &&
3482 conn->io_capability != HCI_IO_NO_INPUT_OUTPUT)
3483 return conn->remote_auth | 0x01;
3484
Timo Mueller7e741702014-04-08 14:21:33 +02003485 /* No MITM protection possible so ignore remote requirement */
3486 return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003487}
3488
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003489static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003490{
3491 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3492 struct hci_conn *conn;
3493
3494 BT_DBG("%s", hdev->name);
3495
3496 hci_dev_lock(hdev);
3497
3498 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003499 if (!conn)
3500 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003501
Johan Hedberg03b555e2011-01-04 15:40:05 +02003502 hci_conn_hold(conn);
3503
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003504 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003505 goto unlock;
3506
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003507 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003508 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003509 struct hci_cp_io_capability_reply cp;
3510
3511 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303512 /* Change the IO capability from KeyboardDisplay
3513 * to DisplayYesNo as it is not supported by BT spec. */
3514 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003515 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Mikel Astizb7f94c82014-04-08 14:21:31 +02003516
3517 /* If we are initiators, there is no remote information yet */
3518 if (conn->remote_auth == 0xff) {
3519 cp.authentication = conn->auth_type;
Mikel Astiz6fd6b912014-04-08 14:21:32 +02003520
Mikel Astizb16c6602014-04-08 14:21:34 +02003521 /* Request MITM protection if our IO caps allow it
3522 * except for the no-bonding case
3523 */
Mikel Astiz6fd6b912014-04-08 14:21:32 +02003524 if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
Mikel Astizb16c6602014-04-08 14:21:34 +02003525 cp.authentication != HCI_AT_NO_BONDING)
Mikel Astiz6fd6b912014-04-08 14:21:32 +02003526 cp.authentication |= 0x01;
Mikel Astizb7f94c82014-04-08 14:21:31 +02003527 } else {
3528 conn->auth_type = hci_get_auth_req(conn);
3529 cp.authentication = conn->auth_type;
3530 }
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003531
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003532 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3533 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003534 cp.oob_data = 0x01;
3535 else
3536 cp.oob_data = 0x00;
3537
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003538 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003539 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003540 } else {
3541 struct hci_cp_io_capability_neg_reply cp;
3542
3543 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003544 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003545
3546 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003547 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003548 }
3549
3550unlock:
3551 hci_dev_unlock(hdev);
3552}
3553
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003554static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003555{
3556 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3557 struct hci_conn *conn;
3558
3559 BT_DBG("%s", hdev->name);
3560
3561 hci_dev_lock(hdev);
3562
3563 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3564 if (!conn)
3565 goto unlock;
3566
Johan Hedberg03b555e2011-01-04 15:40:05 +02003567 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003568 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003569 if (ev->oob_data)
3570 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003571
3572unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003573 hci_dev_unlock(hdev);
3574}
3575
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003576static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3577 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003578{
3579 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003580 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003581 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003582
3583 BT_DBG("%s", hdev->name);
3584
3585 hci_dev_lock(hdev);
3586
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003587 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003588 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003589
Johan Hedberg7a828902011-04-28 11:28:53 -07003590 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3591 if (!conn)
3592 goto unlock;
3593
3594 loc_mitm = (conn->auth_type & 0x01);
3595 rem_mitm = (conn->remote_auth & 0x01);
3596
3597 /* If we require MITM but the remote device can't provide that
Mikel Astiz6fd6b912014-04-08 14:21:32 +02003598 * (it has NoInputNoOutput) then reject the confirmation request
3599 */
3600 if (loc_mitm && conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003601 BT_DBG("Rejecting request: remote device can't provide MITM");
3602 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003603 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003604 goto unlock;
3605 }
3606
3607 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003608 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3609 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003610
3611 /* If we're not the initiators request authorization to
3612 * proceed from user space (mgmt_user_confirm with
3613 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003614 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003615 BT_DBG("Confirming auto-accept as acceptor");
3616 confirm_hint = 1;
3617 goto confirm;
3618 }
3619
Johan Hedberg9f616562011-04-28 11:28:54 -07003620 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003621 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003622
3623 if (hdev->auto_accept_delay > 0) {
3624 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003625 queue_delayed_work(conn->hdev->workqueue,
3626 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003627 goto unlock;
3628 }
3629
Johan Hedberg7a828902011-04-28 11:28:53 -07003630 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003631 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003632 goto unlock;
3633 }
3634
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003635confirm:
Johan Hedberg39adbff2014-03-20 08:18:14 +02003636 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
3637 le32_to_cpu(ev->passkey), confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003638
3639unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003640 hci_dev_unlock(hdev);
3641}
3642
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003643static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3644 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003645{
3646 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3647
3648 BT_DBG("%s", hdev->name);
3649
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003650 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003651 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003652}
3653
Johan Hedberg92a25252012-09-06 18:39:26 +03003654static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3655 struct sk_buff *skb)
3656{
3657 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3658 struct hci_conn *conn;
3659
3660 BT_DBG("%s", hdev->name);
3661
3662 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3663 if (!conn)
3664 return;
3665
3666 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3667 conn->passkey_entered = 0;
3668
3669 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3670 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3671 conn->dst_type, conn->passkey_notify,
3672 conn->passkey_entered);
3673}
3674
3675static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3676{
3677 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3678 struct hci_conn *conn;
3679
3680 BT_DBG("%s", hdev->name);
3681
3682 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3683 if (!conn)
3684 return;
3685
3686 switch (ev->type) {
3687 case HCI_KEYPRESS_STARTED:
3688 conn->passkey_entered = 0;
3689 return;
3690
3691 case HCI_KEYPRESS_ENTERED:
3692 conn->passkey_entered++;
3693 break;
3694
3695 case HCI_KEYPRESS_ERASED:
3696 conn->passkey_entered--;
3697 break;
3698
3699 case HCI_KEYPRESS_CLEARED:
3700 conn->passkey_entered = 0;
3701 break;
3702
3703 case HCI_KEYPRESS_COMPLETED:
3704 return;
3705 }
3706
3707 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3708 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3709 conn->dst_type, conn->passkey_notify,
3710 conn->passkey_entered);
3711}
3712
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003713static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3714 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003715{
3716 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3717 struct hci_conn *conn;
3718
3719 BT_DBG("%s", hdev->name);
3720
3721 hci_dev_lock(hdev);
3722
3723 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003724 if (!conn)
3725 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003726
Johan Hedberg2a611692011-02-19 12:06:00 -03003727 /* To avoid duplicate auth_failed events to user space we check
3728 * the HCI_CONN_AUTH_PEND flag which will be set if we
3729 * initiated the authentication. A traditional auth_complete
3730 * event gets always produced as initiator and is also mapped to
3731 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003732 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003733 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003734 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003735
David Herrmann76a68ba2013-04-06 20:28:37 +02003736 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003737
3738unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003739 hci_dev_unlock(hdev);
3740}
3741
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003742static void hci_remote_host_features_evt(struct hci_dev *hdev,
3743 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003744{
3745 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3746 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003747 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003748
3749 BT_DBG("%s", hdev->name);
3750
3751 hci_dev_lock(hdev);
3752
Johan Hedbergcad718e2013-04-17 15:00:51 +03003753 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3754 if (conn)
3755 memcpy(conn->features[1], ev->features, 8);
3756
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003757 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3758 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003759 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003760
3761 hci_dev_unlock(hdev);
3762}
3763
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003764static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3765 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003766{
3767 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3768 struct oob_data *data;
3769
3770 BT_DBG("%s", hdev->name);
3771
3772 hci_dev_lock(hdev);
3773
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003774 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003775 goto unlock;
3776
Szymon Janc2763eda2011-03-22 13:12:22 +01003777 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3778 if (data) {
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003779 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3780 struct hci_cp_remote_oob_ext_data_reply cp;
Szymon Janc2763eda2011-03-22 13:12:22 +01003781
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003782 bacpy(&cp.bdaddr, &ev->bdaddr);
3783 memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3784 memcpy(cp.randomizer192, data->randomizer192,
3785 sizeof(cp.randomizer192));
3786 memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3787 memcpy(cp.randomizer256, data->randomizer256,
3788 sizeof(cp.randomizer256));
Szymon Janc2763eda2011-03-22 13:12:22 +01003789
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003790 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3791 sizeof(cp), &cp);
3792 } else {
3793 struct hci_cp_remote_oob_data_reply cp;
3794
3795 bacpy(&cp.bdaddr, &ev->bdaddr);
3796 memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3797 memcpy(cp.randomizer, data->randomizer192,
3798 sizeof(cp.randomizer));
3799
3800 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3801 sizeof(cp), &cp);
3802 }
Szymon Janc2763eda2011-03-22 13:12:22 +01003803 } else {
3804 struct hci_cp_remote_oob_data_neg_reply cp;
3805
3806 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003807 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3808 sizeof(cp), &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003809 }
3810
Szymon Jance1ba1f12011-04-06 13:01:59 +02003811unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003812 hci_dev_unlock(hdev);
3813}
3814
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003815static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3816 struct sk_buff *skb)
3817{
3818 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3819 struct hci_conn *hcon, *bredr_hcon;
3820
3821 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3822 ev->status);
3823
3824 hci_dev_lock(hdev);
3825
3826 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3827 if (!hcon) {
3828 hci_dev_unlock(hdev);
3829 return;
3830 }
3831
3832 if (ev->status) {
3833 hci_conn_del(hcon);
3834 hci_dev_unlock(hdev);
3835 return;
3836 }
3837
3838 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3839
3840 hcon->state = BT_CONNECTED;
3841 bacpy(&hcon->dst, &bredr_hcon->dst);
3842
3843 hci_conn_hold(hcon);
3844 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003845 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003846
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003847 hci_conn_add_sysfs(hcon);
3848
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003849 amp_physical_cfm(bredr_hcon, hcon);
3850
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003851 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003852}
3853
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003854static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3855{
3856 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3857 struct hci_conn *hcon;
3858 struct hci_chan *hchan;
3859 struct amp_mgr *mgr;
3860
3861 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3862 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3863 ev->status);
3864
3865 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3866 if (!hcon)
3867 return;
3868
3869 /* Create AMP hchan */
3870 hchan = hci_chan_create(hcon);
3871 if (!hchan)
3872 return;
3873
3874 hchan->handle = le16_to_cpu(ev->handle);
3875
3876 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3877
3878 mgr = hcon->amp_mgr;
3879 if (mgr && mgr->bredr_chan) {
3880 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3881
3882 l2cap_chan_lock(bredr_chan);
3883
3884 bredr_chan->conn->mtu = hdev->block_mtu;
3885 l2cap_logical_cfm(bredr_chan, hchan, 0);
3886 hci_conn_hold(hcon);
3887
3888 l2cap_chan_unlock(bredr_chan);
3889 }
3890}
3891
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003892static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3893 struct sk_buff *skb)
3894{
3895 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3896 struct hci_chan *hchan;
3897
3898 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3899 le16_to_cpu(ev->handle), ev->status);
3900
3901 if (ev->status)
3902 return;
3903
3904 hci_dev_lock(hdev);
3905
3906 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3907 if (!hchan)
3908 goto unlock;
3909
3910 amp_destroy_logical_link(hchan, ev->reason);
3911
3912unlock:
3913 hci_dev_unlock(hdev);
3914}
3915
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003916static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3917 struct sk_buff *skb)
3918{
3919 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3920 struct hci_conn *hcon;
3921
3922 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3923
3924 if (ev->status)
3925 return;
3926
3927 hci_dev_lock(hdev);
3928
3929 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3930 if (hcon) {
3931 hcon->state = BT_CLOSED;
3932 hci_conn_del(hcon);
3933 }
3934
3935 hci_dev_unlock(hdev);
3936}
3937
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003938static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003939{
3940 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3941 struct hci_conn *conn;
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003942 struct smp_irk *irk;
Ville Tervofcd89c02011-02-10 22:38:47 -03003943
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003944 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003945
3946 hci_dev_lock(hdev);
3947
Andre Guedesb47a09b2012-07-27 15:10:15 -03003948 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003949 if (!conn) {
3950 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3951 if (!conn) {
3952 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003953 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003954 }
Andre Guedes29b79882011-05-31 14:20:54 -03003955
3956 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003957
3958 if (ev->role == LE_CONN_ROLE_MASTER) {
3959 conn->out = true;
3960 conn->link_mode |= HCI_LM_MASTER;
3961 }
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02003962
3963 /* If we didn't have a hci_conn object previously
3964 * but we're in master role this must be something
3965 * initiated using a white list. Since white list based
3966 * connections are not "first class citizens" we don't
3967 * have full tracking of them. Therefore, we go ahead
3968 * with a "best effort" approach of determining the
3969 * initiator address based on the HCI_PRIVACY flag.
3970 */
3971 if (conn->out) {
3972 conn->resp_addr_type = ev->bdaddr_type;
3973 bacpy(&conn->resp_addr, &ev->bdaddr);
3974 if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
3975 conn->init_addr_type = ADDR_LE_DEV_RANDOM;
3976 bacpy(&conn->init_addr, &hdev->rpa);
3977 } else {
3978 hci_copy_identity_address(hdev,
3979 &conn->init_addr,
3980 &conn->init_addr_type);
3981 }
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02003982 }
Johan Hedberg9489eca2014-02-28 17:45:46 +02003983 } else {
3984 cancel_delayed_work(&conn->le_conn_timeout);
Ville Tervob62f3282011-02-10 22:38:50 -03003985 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003986
Johan Hedberg80c24ab2014-03-24 20:21:51 +02003987 if (!conn->out) {
3988 /* Set the responder (our side) address type based on
3989 * the advertising address type.
3990 */
3991 conn->resp_addr_type = hdev->adv_addr_type;
3992 if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM)
3993 bacpy(&conn->resp_addr, &hdev->random_addr);
3994 else
3995 bacpy(&conn->resp_addr, &hdev->bdaddr);
3996
3997 conn->init_addr_type = ev->bdaddr_type;
3998 bacpy(&conn->init_addr, &ev->bdaddr);
3999 }
4000
Marcel Holtmannedb4b462014-02-18 15:13:43 -08004001 /* Lookup the identity address from the stored connection
4002 * address and address type.
4003 *
4004 * When establishing connections to an identity address, the
4005 * connection procedure will store the resolvable random
4006 * address first. Now if it can be converted back into the
4007 * identity address, start using the identity address from
4008 * now on.
4009 */
4010 irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02004011 if (irk) {
4012 bacpy(&conn->dst, &irk->bdaddr);
4013 conn->dst_type = irk->addr_type;
4014 }
4015
Andre Guedescd17dec2012-07-27 15:10:16 -03004016 if (ev->status) {
Andre Guedes06c053f2014-02-26 20:21:41 -03004017 hci_le_conn_failed(conn, ev->status);
Andre Guedescd17dec2012-07-27 15:10:16 -03004018 goto unlock;
4019 }
4020
Johan Hedbergb644ba32012-01-17 21:48:47 +02004021 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Marcel Holtmann01fdb0f2014-02-18 14:22:19 -08004022 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004023 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03004024
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03004025 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03004026 conn->handle = __le16_to_cpu(ev->handle);
4027 conn->state = BT_CONNECTED;
4028
Jukka Rissanen18722c22013-12-11 17:05:37 +02004029 if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
4030 set_bit(HCI_CONN_6LOWPAN, &conn->flags);
4031
Ville Tervofcd89c02011-02-10 22:38:47 -03004032 hci_conn_add_sysfs(conn);
4033
4034 hci_proto_connect_cfm(conn, ev->status);
4035
Andre Guedesa4790db2014-02-26 20:21:47 -03004036 hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
4037
Ville Tervofcd89c02011-02-10 22:38:47 -03004038unlock:
4039 hci_dev_unlock(hdev);
4040}
4041
Andre Guedesa4790db2014-02-26 20:21:47 -03004042/* This function requires the caller holds hdev->lock */
4043static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4044 u8 addr_type)
4045{
4046 struct hci_conn *conn;
Andre Guedes5b906a82014-02-26 20:21:53 -03004047 struct smp_irk *irk;
4048
4049 /* If this is a resolvable address, we should resolve it and then
4050 * update address and address type variables.
4051 */
4052 irk = hci_get_irk(hdev, addr, addr_type);
4053 if (irk) {
4054 addr = &irk->bdaddr;
4055 addr_type = irk->addr_type;
4056 }
Andre Guedesa4790db2014-02-26 20:21:47 -03004057
4058 if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
4059 return;
4060
4061 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
4062 HCI_AT_NO_BONDING);
4063 if (!IS_ERR(conn))
4064 return;
4065
4066 switch (PTR_ERR(conn)) {
4067 case -EBUSY:
4068 /* If hci_connect() returns -EBUSY it means there is already
4069 * an LE connection attempt going on. Since controllers don't
4070 * support more than one connection attempt at the time, we
4071 * don't consider this an error case.
4072 */
4073 break;
4074 default:
4075 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
4076 }
4077}
4078
Johan Hedberg4af605d2014-03-24 10:48:00 +02004079static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
4080 u8 bdaddr_type, s8 rssi, u8 *data, u8 len)
4081{
Johan Hedbergb9a63282014-03-25 10:51:52 +02004082 struct discovery_state *d = &hdev->discovery;
Johan Hedberg474ee062014-03-25 14:34:59 +02004083 bool match;
Johan Hedbergb9a63282014-03-25 10:51:52 +02004084
Johan Hedbergca5c4be2014-03-25 10:30:46 +02004085 /* Passive scanning shouldn't trigger any device found events */
4086 if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
4087 if (type == LE_ADV_IND || type == LE_ADV_DIRECT_IND)
4088 check_pending_le_conn(hdev, bdaddr, bdaddr_type);
4089 return;
4090 }
Johan Hedberg4af605d2014-03-24 10:48:00 +02004091
Johan Hedbergb9a63282014-03-25 10:51:52 +02004092 /* If there's nothing pending either store the data from this
4093 * event or send an immediate device found event if the data
4094 * should not be stored for later.
4095 */
4096 if (!has_pending_adv_report(hdev)) {
4097 /* If the report will trigger a SCAN_REQ store it for
4098 * later merging.
4099 */
4100 if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
4101 store_pending_adv_report(hdev, bdaddr, bdaddr_type,
Johan Hedbergff5cd292014-03-25 14:40:52 +02004102 rssi, data, len);
Johan Hedbergb9a63282014-03-25 10:51:52 +02004103 return;
4104 }
4105
4106 mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
4107 rssi, 0, 1, data, len, NULL, 0);
4108 return;
4109 }
4110
Johan Hedberg474ee062014-03-25 14:34:59 +02004111 /* Check if the pending report is for the same device as the new one */
4112 match = (!bacmp(bdaddr, &d->last_adv_addr) &&
4113 bdaddr_type == d->last_adv_addr_type);
4114
Johan Hedbergb9a63282014-03-25 10:51:52 +02004115 /* If the pending data doesn't match this report or this isn't a
4116 * scan response (e.g. we got a duplicate ADV_IND) then force
4117 * sending of the pending data.
4118 */
Johan Hedberg474ee062014-03-25 14:34:59 +02004119 if (type != LE_ADV_SCAN_RSP || !match) {
4120 /* Send out whatever is in the cache, but skip duplicates */
4121 if (!match)
4122 mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
Johan Hedbergff5cd292014-03-25 14:40:52 +02004123 d->last_adv_addr_type, NULL,
4124 d->last_adv_rssi, 0, 1,
4125 d->last_adv_data,
Johan Hedberg474ee062014-03-25 14:34:59 +02004126 d->last_adv_data_len, NULL, 0);
Johan Hedbergb9a63282014-03-25 10:51:52 +02004127
4128 /* If the new report will trigger a SCAN_REQ store it for
4129 * later merging.
4130 */
4131 if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
4132 store_pending_adv_report(hdev, bdaddr, bdaddr_type,
Johan Hedbergff5cd292014-03-25 14:40:52 +02004133 rssi, data, len);
Johan Hedbergb9a63282014-03-25 10:51:52 +02004134 return;
4135 }
4136
4137 /* The advertising reports cannot be merged, so clear
4138 * the pending report and send out a device found event.
4139 */
4140 clear_pending_adv_report(hdev);
Johan Hedberg5c5b93e2014-03-29 08:39:53 +02004141 mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
4142 rssi, 0, 1, data, len, NULL, 0);
Johan Hedbergb9a63282014-03-25 10:51:52 +02004143 return;
4144 }
4145
4146 /* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and
4147 * the new event is a SCAN_RSP. We can therefore proceed with
4148 * sending a merged device found event.
4149 */
4150 mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
4151 d->last_adv_addr_type, NULL, rssi, 0, 1, data, len,
4152 d->last_adv_data, d->last_adv_data_len);
4153 clear_pending_adv_report(hdev);
Johan Hedberg4af605d2014-03-24 10:48:00 +02004154}
4155
Gustavo Padovan6039aa72012-05-23 04:04:18 -03004156static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03004157{
Andre Guedese95beb42011-09-26 20:48:35 -03004158 u8 num_reports = skb->data[0];
4159 void *ptr = &skb->data[1];
Andre Guedes9aa04c92011-05-26 16:23:51 -03004160
Andre Guedesa4790db2014-02-26 20:21:47 -03004161 hci_dev_lock(hdev);
4162
Andre Guedese95beb42011-09-26 20:48:35 -03004163 while (num_reports--) {
4164 struct hci_ev_le_advertising_info *ev = ptr;
Johan Hedberg4af605d2014-03-24 10:48:00 +02004165 s8 rssi;
Andre Guedesa4790db2014-02-26 20:21:47 -03004166
Andre Guedes3c9e9192012-01-10 18:20:50 -03004167 rssi = ev->data[ev->length];
Johan Hedberg4af605d2014-03-24 10:48:00 +02004168 process_adv_report(hdev, ev->evt_type, &ev->bdaddr,
4169 ev->bdaddr_type, rssi, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03004170
Andre Guedese95beb42011-09-26 20:48:35 -03004171 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03004172 }
Andre Guedesa4790db2014-02-26 20:21:47 -03004173
4174 hci_dev_unlock(hdev);
Andre Guedes9aa04c92011-05-26 16:23:51 -03004175}
4176
Gustavo Padovan6039aa72012-05-23 04:04:18 -03004177static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004178{
4179 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
4180 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004181 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004182 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004183 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004184
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004185 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004186
4187 hci_dev_lock(hdev);
4188
4189 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004190 if (conn == NULL)
4191 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004192
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08004193 ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->out);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004194 if (ltk == NULL)
4195 goto not_found;
4196
4197 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004198 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004199
4200 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03004201 conn->pending_sec_level = BT_SECURITY_HIGH;
4202 else
4203 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004204
Andre Guedes89cbb4d2013-07-31 16:25:29 -03004205 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004206
4207 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
4208
Claudio Takahasi5981a882013-07-25 16:34:24 -03004209 /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
4210 * temporary key used to encrypt a connection following
4211 * pairing. It is used during the Encrypted Session Setup to
4212 * distribute the keys. Later, security can be re-established
4213 * using a distributed LTK.
4214 */
4215 if (ltk->type == HCI_SMP_STK_SLAVE) {
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004216 list_del(&ltk->list);
4217 kfree(ltk);
4218 }
4219
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004220 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004221
4222 return;
4223
4224not_found:
4225 neg.handle = ev->handle;
4226 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
4227 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004228}
4229
Gustavo Padovan6039aa72012-05-23 04:04:18 -03004230static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03004231{
4232 struct hci_ev_le_meta *le_ev = (void *) skb->data;
4233
4234 skb_pull(skb, sizeof(*le_ev));
4235
4236 switch (le_ev->subevent) {
4237 case HCI_EV_LE_CONN_COMPLETE:
4238 hci_le_conn_complete_evt(hdev, skb);
4239 break;
4240
Andre Guedes9aa04c92011-05-26 16:23:51 -03004241 case HCI_EV_LE_ADVERTISING_REPORT:
4242 hci_le_adv_report_evt(hdev, skb);
4243 break;
4244
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004245 case HCI_EV_LE_LTK_REQ:
4246 hci_le_ltk_request_evt(hdev, skb);
4247 break;
4248
Ville Tervofcd89c02011-02-10 22:38:47 -03004249 default:
4250 break;
4251 }
4252}
4253
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004254static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
4255{
4256 struct hci_ev_channel_selected *ev = (void *) skb->data;
4257 struct hci_conn *hcon;
4258
4259 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
4260
4261 skb_pull(skb, sizeof(*ev));
4262
4263 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
4264 if (!hcon)
4265 return;
4266
4267 amp_read_loc_assoc_final_data(hdev, hcon);
4268}
4269
Linus Torvalds1da177e2005-04-16 15:20:36 -07004270void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
4271{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004272 struct hci_event_hdr *hdr = (void *) skb->data;
4273 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004274
Johan Hedbergb6ddb632013-04-02 13:34:31 +03004275 hci_dev_lock(hdev);
4276
4277 /* Received events are (currently) only needed when a request is
4278 * ongoing so avoid unnecessary memory allocation.
4279 */
4280 if (hdev->req_status == HCI_REQ_PEND) {
4281 kfree_skb(hdev->recv_evt);
4282 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
4283 }
4284
4285 hci_dev_unlock(hdev);
4286
Linus Torvalds1da177e2005-04-16 15:20:36 -07004287 skb_pull(skb, HCI_EVENT_HDR_SIZE);
4288
Johan Hedberg02350a72013-04-03 21:50:29 +03004289 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02004290 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
4291 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03004292
4293 hci_req_cmd_complete(hdev, opcode, 0);
4294 }
4295
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004296 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004297 case HCI_EV_INQUIRY_COMPLETE:
4298 hci_inquiry_complete_evt(hdev, skb);
4299 break;
4300
4301 case HCI_EV_INQUIRY_RESULT:
4302 hci_inquiry_result_evt(hdev, skb);
4303 break;
4304
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004305 case HCI_EV_CONN_COMPLETE:
4306 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02004307 break;
4308
Linus Torvalds1da177e2005-04-16 15:20:36 -07004309 case HCI_EV_CONN_REQUEST:
4310 hci_conn_request_evt(hdev, skb);
4311 break;
4312
Linus Torvalds1da177e2005-04-16 15:20:36 -07004313 case HCI_EV_DISCONN_COMPLETE:
4314 hci_disconn_complete_evt(hdev, skb);
4315 break;
4316
Linus Torvalds1da177e2005-04-16 15:20:36 -07004317 case HCI_EV_AUTH_COMPLETE:
4318 hci_auth_complete_evt(hdev, skb);
4319 break;
4320
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004321 case HCI_EV_REMOTE_NAME:
4322 hci_remote_name_evt(hdev, skb);
4323 break;
4324
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325 case HCI_EV_ENCRYPT_CHANGE:
4326 hci_encrypt_change_evt(hdev, skb);
4327 break;
4328
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004329 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
4330 hci_change_link_key_complete_evt(hdev, skb);
4331 break;
4332
4333 case HCI_EV_REMOTE_FEATURES:
4334 hci_remote_features_evt(hdev, skb);
4335 break;
4336
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004337 case HCI_EV_CMD_COMPLETE:
4338 hci_cmd_complete_evt(hdev, skb);
4339 break;
4340
4341 case HCI_EV_CMD_STATUS:
4342 hci_cmd_status_evt(hdev, skb);
4343 break;
4344
4345 case HCI_EV_ROLE_CHANGE:
4346 hci_role_change_evt(hdev, skb);
4347 break;
4348
4349 case HCI_EV_NUM_COMP_PKTS:
4350 hci_num_comp_pkts_evt(hdev, skb);
4351 break;
4352
4353 case HCI_EV_MODE_CHANGE:
4354 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004355 break;
4356
4357 case HCI_EV_PIN_CODE_REQ:
4358 hci_pin_code_request_evt(hdev, skb);
4359 break;
4360
4361 case HCI_EV_LINK_KEY_REQ:
4362 hci_link_key_request_evt(hdev, skb);
4363 break;
4364
4365 case HCI_EV_LINK_KEY_NOTIFY:
4366 hci_link_key_notify_evt(hdev, skb);
4367 break;
4368
4369 case HCI_EV_CLOCK_OFFSET:
4370 hci_clock_offset_evt(hdev, skb);
4371 break;
4372
Marcel Holtmanna8746412008-07-14 20:13:46 +02004373 case HCI_EV_PKT_TYPE_CHANGE:
4374 hci_pkt_type_change_evt(hdev, skb);
4375 break;
4376
Marcel Holtmann85a1e932005-08-09 20:28:02 -07004377 case HCI_EV_PSCAN_REP_MODE:
4378 hci_pscan_rep_mode_evt(hdev, skb);
4379 break;
4380
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004381 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
4382 hci_inquiry_result_with_rssi_evt(hdev, skb);
4383 break;
4384
4385 case HCI_EV_REMOTE_EXT_FEATURES:
4386 hci_remote_ext_features_evt(hdev, skb);
4387 break;
4388
4389 case HCI_EV_SYNC_CONN_COMPLETE:
4390 hci_sync_conn_complete_evt(hdev, skb);
4391 break;
4392
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004393 case HCI_EV_EXTENDED_INQUIRY_RESULT:
4394 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004395 break;
4396
Johan Hedberg1c2e0042012-06-08 23:31:13 +08004397 case HCI_EV_KEY_REFRESH_COMPLETE:
4398 hci_key_refresh_complete_evt(hdev, skb);
4399 break;
4400
Marcel Holtmann04936842008-07-14 20:13:48 +02004401 case HCI_EV_IO_CAPA_REQUEST:
4402 hci_io_capa_request_evt(hdev, skb);
4403 break;
4404
Johan Hedberg03b555e2011-01-04 15:40:05 +02004405 case HCI_EV_IO_CAPA_REPLY:
4406 hci_io_capa_reply_evt(hdev, skb);
4407 break;
4408
Johan Hedberga5c29682011-02-19 12:05:57 -03004409 case HCI_EV_USER_CONFIRM_REQUEST:
4410 hci_user_confirm_request_evt(hdev, skb);
4411 break;
4412
Brian Gix1143d452011-11-23 08:28:34 -08004413 case HCI_EV_USER_PASSKEY_REQUEST:
4414 hci_user_passkey_request_evt(hdev, skb);
4415 break;
4416
Johan Hedberg92a25252012-09-06 18:39:26 +03004417 case HCI_EV_USER_PASSKEY_NOTIFY:
4418 hci_user_passkey_notify_evt(hdev, skb);
4419 break;
4420
4421 case HCI_EV_KEYPRESS_NOTIFY:
4422 hci_keypress_notify_evt(hdev, skb);
4423 break;
4424
Marcel Holtmann04936842008-07-14 20:13:48 +02004425 case HCI_EV_SIMPLE_PAIR_COMPLETE:
4426 hci_simple_pair_complete_evt(hdev, skb);
4427 break;
4428
Marcel Holtmann41a96212008-07-14 20:13:48 +02004429 case HCI_EV_REMOTE_HOST_FEATURES:
4430 hci_remote_host_features_evt(hdev, skb);
4431 break;
4432
Ville Tervofcd89c02011-02-10 22:38:47 -03004433 case HCI_EV_LE_META:
4434 hci_le_meta_evt(hdev, skb);
4435 break;
4436
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004437 case HCI_EV_CHANNEL_SELECTED:
4438 hci_chan_selected_evt(hdev, skb);
4439 break;
4440
Szymon Janc2763eda2011-03-22 13:12:22 +01004441 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
4442 hci_remote_oob_data_request_evt(hdev, skb);
4443 break;
4444
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03004445 case HCI_EV_PHY_LINK_COMPLETE:
4446 hci_phy_link_complete_evt(hdev, skb);
4447 break;
4448
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004449 case HCI_EV_LOGICAL_LINK_COMPLETE:
4450 hci_loglink_complete_evt(hdev, skb);
4451 break;
4452
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02004453 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
4454 hci_disconn_loglink_complete_evt(hdev, skb);
4455 break;
4456
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02004457 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
4458 hci_disconn_phylink_complete_evt(hdev, skb);
4459 break;
4460
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02004461 case HCI_EV_NUM_COMP_BLOCKS:
4462 hci_num_comp_blocks_evt(hdev, skb);
4463 break;
4464
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004465 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004466 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004467 break;
4468 }
4469
4470 kfree_skb(skb);
4471 hdev->stat.evt_rx++;
4472}